forked from I2P_Developers/i2p.i2p
Compare commits
216 Commits
i2p_0_3_4_
...
i2p_0_4_1_
Author | SHA1 | Date | |
---|---|---|---|
a14da92e1d | |||
2b54d850ea | |||
a63c1b19fc | |||
34f74cd6ef | |||
c0b8e62135 | |||
ea24166b8e | |||
178b229d66 | |||
276493da65 | |||
e85dadfef2 | |||
1c70efb350 | |||
6804a0c564 | |||
6eb7ecc2d4 | |||
f4956b06b6 | |||
9a2f7c2660 | |||
b6017c558a | |||
62ed6c6a58 | |||
24966c812f | |||
ea8dc2e0af | |||
010b285e67 | |||
774231f347 | |||
ff1dfd8f25 | |||
2741ac195d | |||
cf780e296e | |||
0361246db0 | |||
63355ecd5b | |||
0f54ba59fb | |||
b67b243ebd | |||
4c29c20613 | |||
4c2619d948 | |||
ea5662a4a2 | |||
7c1ce777a1 | |||
3bb85f2d61 | |||
93e36b3113 | |||
932fb670e3 | |||
54dce61a95 | |||
e686c0e0a2 | |||
05acf32f39 | |||
67064012c9 | |||
10e93c3b1b | |||
5b2ec1cbb5 | |||
972f701c5c | |||
51285efbc3 | |||
e2635705f9 | |||
7762107543 | |||
9123ad89c8 | |||
39f3d6cc80 | |||
af5665f67c | |||
c2175cc692 | |||
1ef371a467 | |||
58461ff5bb | |||
665959da90 | |||
8e63974f94 | |||
eae86f54ba | |||
30128a122d | |||
56e22a39ac | |||
6ceb330baa | |||
f30509c7ba | |||
9489136bd6 | |||
05cd3d736b | |||
29b17772e5 | |||
6151d63eac | |||
e57aa68854 | |||
73fa6d9bd0 | |||
da3c4b87c1 | |||
0eedc1b128 | |||
db339d40de | |||
f72aa7884d | |||
1434f1bb40 | |||
6bc92b26a7 | |||
63937d0fba | |||
7b86edaf7f | |||
49d4e565c6 | |||
44c54ecc16 | |||
6e543f825d | |||
591800a28a | |||
3340d74e3f | |||
446d863106 | |||
8b2d27a916 | |||
9b31f2257d | |||
252ec98e24 | |||
77dde5711b | |||
94e891880b | |||
c414b3fad2 | |||
c0b63ee7a8 | |||
6fbbfbaa43 | |||
4d663e4500 | |||
88ba2436c9 | |||
bfda22ad57 | |||
b888f17672 | |||
8aa07e6f12 | |||
79e973af65 | |||
83c6fd43e5 | |||
1323d89912 | |||
6b89996b0b | |||
8a9a60410c | |||
09e8678369 | |||
2ff7efadc2 | |||
5f3fcd2f37 | |||
7dffae4620 | |||
ce2e7305d4 | |||
4783b09f03 | |||
15c089ca9c | |||
e93a2ddd93 | |||
57b9c40609 | |||
caaadd63ec | |||
ca1b707fab | |||
a0499451a5 | |||
bbdf1a0b30 | |||
bcd5230854 | |||
5ec3d2a587 | |||
9cb2be6ec4 | |||
4e90ca0b26 | |||
8c4c72c8b5 | |||
8690d4d7a9 | |||
d5d9c9b483 | |||
0de8129457 | |||
13f70ad42c | |||
49d7b568df | |||
93afcd5c0c | |||
07ef3582f7 | |||
53c7ff14df | |||
6b993688fc | |||
b9e667e155 | |||
3cd26781b0 | |||
2d20ac6f29 | |||
944d467654 | |||
f68271c3d7 | |||
4eb5070753 | |||
f57adc9cc4 | |||
3e0b7bfeff | |||
faa78c67d8 | |||
a5ed02eb1c | |||
bfe11110aa | |||
d8b1d2382d | |||
7881a13610 | |||
aaa328950e | |||
d8eb1a0a4f | |||
e3379b31cb | |||
f36ce3d245 | |||
c73f3385c0 | |||
2eb8b84bbd | |||
b31378ad1a | |||
53213bb553 | |||
36b446c012 | |||
ca70fc8dc8 | |||
18ff889b56 | |||
fab3c0df3e | |||
7e7f97d72a | |||
3a1fcf2865 | |||
fd85416088 | |||
18a6a9e965 | |||
eed8d9c61b | |||
cbe12adbe6 | |||
84f8931ddd | |||
db135e502c | |||
6f205f8adf | |||
e81c1df19f | |||
71577c9b0e | |||
c88c245094 | |||
30ce04bc84 | |||
205d8f7db2 | |||
d70c22d73f | |||
920161bc07 | |||
cdafefebd3 | |||
f220300212 | |||
a2b86acc22 | |||
8e53028d78 | |||
852dfa4abf | |||
5d6845a58a | |||
be846e69c5 | |||
eef8c06b39 | |||
54aa0fdb11 | |||
3c62a5d2b4 | |||
0fe70b660a | |||
4f787ddb03 | |||
be33752eb3 | |||
a88dbbe5ba | |||
9b4144b815 | |||
bce5b44275 | |||
9f7320fa67 | |||
e9310ee8dd | |||
be93db51f7 | |||
8e3e8ada32 | |||
4564a6e8fd | |||
240190fa8f | |||
4ca7c0d978 | |||
190d0f9304 | |||
b8d2a363fb | |||
2382785240 | |||
476994595c | |||
287969f169 | |||
ca93c52161 | |||
b126b19e03 | |||
2c907060d4 | |||
e28c0d0b4a | |||
918df735ed | |||
294936d137 | |||
115da03a23 | |||
cc085755aa | |||
cb5e3efd8a | |||
274fd0b528 | |||
1431d1fecd | |||
dc3d6bfc43 | |||
c9d4745a59 | |||
921aef7f2c | |||
3c772f1974 | |||
bee9c7ee17 | |||
75ca438f2f | |||
9ea6eed22f | |||
56f13c53ce | |||
fbc63c957a | |||
6052a9382b | |||
f7f05cfc8b | |||
f4754d7481 | |||
7dc8d0cfec | |||
846c393168 |
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Bogobot.java
|
||||
* 2004 The I2P Project
|
||||
* http://www.i2p.net
|
||||
* This code is public domain.
|
||||
*/
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Bogoparser.java
|
||||
* 2004 The I2P Project
|
||||
* http://www.i2p.net
|
||||
* This code is public domain.
|
||||
*/
|
||||
|
||||
|
@ -5,9 +5,10 @@
|
||||
<!-- -->
|
||||
<!-- build-eclipse.xml -->
|
||||
<!-- 2004 The I2P Project -->
|
||||
<!-- http://www.i2p.net -->
|
||||
<!-- This code is public domain. -->
|
||||
<!-- -->
|
||||
<!-- author hypercubus, oOo -->
|
||||
<!-- authors: hypercubus, oOo -->
|
||||
<!-- version 0.4 -->
|
||||
<!-- ********************************************************** -->
|
||||
|
||||
|
@ -5,9 +5,10 @@
|
||||
<!-- -->
|
||||
<!-- build.xml -->
|
||||
<!-- 2004 The I2P Project -->
|
||||
<!-- http://www.i2p.net -->
|
||||
<!-- This code is public domain. -->
|
||||
<!-- -->
|
||||
<!-- author hypercubus, oOo -->
|
||||
<!-- authors: hypercubus, oOo -->
|
||||
<!-- version 0.4 -->
|
||||
<!-- ********************************************************** -->
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,87 +0,0 @@
|
||||
#
|
||||
# This Makefile is compatible with GNU Make and should work on Cygwin
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating environment
|
||||
#
|
||||
|
||||
OS = CYGWIN
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
|
||||
BINDIR = bin
|
||||
LOGDIR = log
|
||||
OBJDIR = obj
|
||||
SRCDIR = src
|
||||
|
||||
SAMINCDIR = ../sam/c/inc
|
||||
SAMLIBDIR = ../sam/c/lib
|
||||
TOMCRYPTDIR = $(HOME)/libtomcrypt-0.96
|
||||
|
||||
#
|
||||
# Programs
|
||||
#
|
||||
|
||||
CC = g++
|
||||
|
||||
#
|
||||
# Flags
|
||||
#
|
||||
|
||||
CFLAGS = -g -march=i486 -pipe -Wall
|
||||
CFLAGS += -DOS=$(OS)
|
||||
|
||||
#
|
||||
# Libraries
|
||||
#
|
||||
|
||||
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
|
||||
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
|
||||
LIBS = -lsam -ltomcrypt -lpthread
|
||||
|
||||
#
|
||||
# Object files
|
||||
#
|
||||
|
||||
OBJS = $(OBJDIR)/bigint.o \
|
||||
$(OBJDIR)/chk.o \
|
||||
$(OBJDIR)/config.o \
|
||||
$(OBJDIR)/logger.o \
|
||||
$(OBJDIR)/main.o \
|
||||
$(OBJDIR)/mutex.o \
|
||||
$(OBJDIR)/peers.o \
|
||||
$(OBJDIR)/random.o \
|
||||
$(OBJDIR)/rpc.o \
|
||||
$(OBJDIR)/sam.o \
|
||||
$(OBJDIR)/sha1.o \
|
||||
$(OBJDIR)/thread.o
|
||||
|
||||
#
|
||||
# Build rules
|
||||
#
|
||||
|
||||
all: depend enclave
|
||||
|
||||
depend:
|
||||
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
enclave: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
|
||||
|
||||
#
|
||||
# Cleanup rules
|
||||
#
|
||||
|
||||
clean:
|
||||
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
|
||||
|
||||
clean-logs:
|
||||
-rm -f $(LOGDIR)/*
|
||||
|
||||
tidy: clean clean-logs
|
@ -1,87 +0,0 @@
|
||||
#
|
||||
# This Makefile is compatible with GNU Make and should work on Linux (generic)
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating environment
|
||||
#
|
||||
|
||||
OS = LINUX
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
|
||||
BINDIR = bin
|
||||
LOGDIR = log
|
||||
OBJDIR = obj
|
||||
SRCDIR = src
|
||||
|
||||
SAMINCDIR = ../sam/c/inc
|
||||
SAMLIBDIR = ../sam/c/lib
|
||||
TOMCRYPTDIR = $(HOME)/libtomcrypt-0.96
|
||||
|
||||
#
|
||||
# Programs
|
||||
#
|
||||
|
||||
CC = g++
|
||||
|
||||
#
|
||||
# Flags
|
||||
#
|
||||
|
||||
CFLAGS = -g -march=i486 -pipe -Wall
|
||||
CFLAGS += -DOS=$(OS)
|
||||
|
||||
#
|
||||
# Libraries
|
||||
#
|
||||
|
||||
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
|
||||
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
|
||||
LIBS = -lsam -ltomcrypt -lpthread
|
||||
|
||||
#
|
||||
# Object files
|
||||
#
|
||||
|
||||
OBJS = $(OBJDIR)/bigint.o \
|
||||
$(OBJDIR)/chk.o \
|
||||
$(OBJDIR)/config.o \
|
||||
$(OBJDIR)/logger.o \
|
||||
$(OBJDIR)/main.o \
|
||||
$(OBJDIR)/mutex.o \
|
||||
$(OBJDIR)/peers.o \
|
||||
$(OBJDIR)/random.o \
|
||||
$(OBJDIR)/rpc.o \
|
||||
$(OBJDIR)/sam.o \
|
||||
$(OBJDIR)/sha1.o \
|
||||
$(OBJDIR)/thread.o
|
||||
|
||||
#
|
||||
# Build rules
|
||||
#
|
||||
|
||||
all: depend enclave
|
||||
|
||||
depend:
|
||||
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
enclave: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
|
||||
|
||||
#
|
||||
# Cleanup rules
|
||||
#
|
||||
|
||||
clean:
|
||||
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
|
||||
|
||||
clean-logs:
|
||||
-rm -f $(LOGDIR)/*
|
||||
|
||||
tidy: clean clean-logs
|
@ -1,87 +0,0 @@
|
||||
#
|
||||
# This Makefile is compatible with GNU Make and should work on Windows (Mingw)
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating environment
|
||||
#
|
||||
|
||||
OS = MINGW
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
|
||||
BINDIR = bin
|
||||
LOGDIR = log
|
||||
OBJDIR = obj
|
||||
SRCDIR = src
|
||||
|
||||
SAMINCDIR = C:\cygwin\home\Administrator\cvs\i2p\apps\sam\c\inc
|
||||
SAMLIBDIR = C:\cygwin\home\Administrator\cvs\i2p\apps\sam\c\lib
|
||||
TOMCRYPTDIR = C:\cygwin\home\Administrator\libtomcrypt-0.96
|
||||
|
||||
#
|
||||
# Programs
|
||||
#
|
||||
|
||||
CC = C:\Dev-Cpp\bin\g++
|
||||
|
||||
#
|
||||
# Flags
|
||||
#
|
||||
|
||||
CFLAGS = -g -march=i486 -pipe -Wall
|
||||
CFLAGS += -DOS=$(OS)
|
||||
|
||||
#
|
||||
# Libraries
|
||||
#
|
||||
|
||||
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
|
||||
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
|
||||
LIBS = -lsam -ltomcrypt
|
||||
|
||||
#
|
||||
# Object files
|
||||
#
|
||||
|
||||
OBJS = $(OBJDIR)/bigint.o \
|
||||
$(OBJDIR)/chk.o \
|
||||
$(OBJDIR)/config.o \
|
||||
$(OBJDIR)/logger.o \
|
||||
$(OBJDIR)/main.o \
|
||||
$(OBJDIR)/mutex.o \
|
||||
$(OBJDIR)/peers.o \
|
||||
$(OBJDIR)/random.o \
|
||||
$(OBJDIR)/rpc.o \
|
||||
$(OBJDIR)/sam.o \
|
||||
$(OBJDIR)/sha1.o \
|
||||
$(OBJDIR)/thread.o
|
||||
|
||||
#
|
||||
# Build rules
|
||||
#
|
||||
|
||||
all: depend enclave
|
||||
|
||||
depend:
|
||||
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.cpp > .depend
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
enclave: $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $(BINDIR)/enclave $(OBJS) $(LIBS)
|
||||
|
||||
#
|
||||
# Cleanup rules
|
||||
#
|
||||
|
||||
clean:
|
||||
-rm -f $(BINDIR)/* $(OBJDIR)/* .depend
|
||||
|
||||
clean-logs:
|
||||
-rm -f $(LOGDIR)/*
|
||||
|
||||
tidy: clean clean-logs
|
@ -1,32 +0,0 @@
|
||||
#
|
||||
# This is the Enclave configuration file. Lines starting with # and blank lines
|
||||
# are ignored.
|
||||
#
|
||||
|
||||
# The DNS name or IP address of the SAM server you will be using
|
||||
samhost=localhost
|
||||
|
||||
# The TCP port the SAM server is listening on
|
||||
samport=7656
|
||||
|
||||
# The destination name of this program. This can be anything. If you run
|
||||
# multiple copies of Enclave off the same SAM server then each one has to have a
|
||||
# unique name.
|
||||
samname=enclave
|
||||
|
||||
# The depth used for incoming and outgoing I2P tunnels. Using a depth of 2 is
|
||||
# the default and a good choice. You can set it to 0 if you don't care about
|
||||
# anonymity and just want speed.
|
||||
tunneldepth=0
|
||||
|
||||
# The location of the peer references file. You can use an absolute or relative
|
||||
# path, but absolute paths are safer.
|
||||
references=cfg/peers.ref
|
||||
|
||||
# Record every log message at or above this priority level
|
||||
# debug = 0, minor = 1, info = 2, warn = 3, error = 4
|
||||
loglevel=0
|
||||
|
||||
# The location of the Enclave log file. You can use an absolute or relative
|
||||
# path, but absolute paths are safer.
|
||||
logfile=log/enclave.log
|
@ -1,2 +0,0 @@
|
||||
4KpEG0uUvTM~IZKuWZZifdmh5UU6evIPG0tE3ppoqy37AY2NJrsM8BU0EkT1SG-g18qSW9UHDp7qs7m~WzeWTXyYggEb6k6-e0GYC2Cj8ED8JV58-2~cFZumVNJ2d1hns-MGX7RZv2lz3Cz2ZVhfZxSIw9UnpV-kwVn7sQ7PBCvJYE4INbp5OlRQH1-3lXiUheoJfeZpegGTUSHUwIRWglX7w87YF~LCbJMYXDgMyA3SaxsZaun7Wc8ku4bqtbmG9u15XlmqimLUUmDG0cw77HJzqxnR1C1hx0wf-9zgH6u4jwTWk92w5tZJZSv1SHKejlPkIbRNAhZv5wroyZsn6T0koV~kTVCvbUEwILho-rHn4A6C2jLQifwE9aucziBTVq3YLK2urf1wI1jLh98iFNav40S~B2w-4xZFAQ49bOdWzY4KmVIjocVhfGi~RLl5bHD1TEJS7nOaDhI8qCSe7mR0XzZgQ~iROR~XowlwKXBzNPjKED7yN8GgV2pWRGNYAAAA
|
||||
WiotuvEjGpSz7q14eZGYFpD0xNt3V~nxZdDDgKc~whkW-pardZyz~wZipHXLIOvniThDL2rxJ~OW7RxgUycCph4x--NL51kEJhMWZ~bgxPioxw-T4JGQ9LSNndt9xNOf6yhEqyokqyEOEeJjw6m2e7RX7mTRffmTlCdu6uH6rVEk22o4Uu5S26p6-LS2k9lRyMWitFd~t9cnOgLTZTE~h4d-UlAd1BGxpCTlGWcaynOQzKKtljZknZMF9Qv19MxT83t18~3IURb6aOLlC4oih9pMt1pHouZuOaStKA7cGLsXUAhSB31BvK8l4R7VhgcudwJ9EQZkZQee51hcng7K1Yqmd4lnjHHuf1mDk0YXBAWDZOM0-oEwkJWumGuYl0NUtLhNlFrBjenbjACx88qhfy6mkXfo8c-c2QqEXuD2xt4OVqrWxBTIrr1pR-E1NdIxzIvOlCbrRXaqxqu-wnrrG2vCO-1zu9NHacCVjXD7AR7p3T628wPdCUzj2~rZRcCkAAAA
|
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "time.hpp"
|
||||
#include "logger.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
/*
|
||||
* Closes the log file
|
||||
*/
|
||||
void Logger::close()
|
||||
{
|
||||
logf_m.lock();
|
||||
if (logf == NULL) {
|
||||
logf_m.unlock();
|
||||
return;
|
||||
}
|
||||
if (fclose(logf) == EOF) {
|
||||
cerr_m.lock();
|
||||
cerr << "fclose() failed: " << strerror(errno) << '\n';
|
||||
cerr_m.unlock();
|
||||
}
|
||||
logf = NULL;
|
||||
logf_m.unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a line to the log file. Uses variable arguments just like printf().
|
||||
*/
|
||||
void Logger::log(priority_t priority, const char* format, ...)
|
||||
{
|
||||
if (priority < get_loglevel())
|
||||
return;
|
||||
|
||||
char ll;
|
||||
switch (priority) {
|
||||
case Logger::DEBUG:
|
||||
ll = 'D';
|
||||
break;
|
||||
case Logger::MINOR:
|
||||
ll = 'M';
|
||||
break;
|
||||
case Logger::INFO:
|
||||
ll = 'I';
|
||||
break;
|
||||
case Logger::WARN:
|
||||
ll = 'W';
|
||||
break;
|
||||
case Logger::ERROR:
|
||||
ll = 'E';
|
||||
break;
|
||||
default:
|
||||
ll = '?';
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
Time t;
|
||||
logf_m.lock();
|
||||
|
||||
if (logf != NULL) {
|
||||
/*
|
||||
* Remember! If you change the format here, change it in the else too
|
||||
*/
|
||||
fprintf(logf, "%c %s ", ll, t.utc().c_str());
|
||||
vfprintf(logf, format, ap);
|
||||
fputc('\n', logf);
|
||||
if (fflush(logf) == EOF) {
|
||||
cerr_m.lock();
|
||||
cerr << "fflush() failed: " << strerror(errno) << '\n';
|
||||
cerr_m.unlock();
|
||||
}
|
||||
} else {
|
||||
// if they don't have an open log file, just use stderr
|
||||
fprintf(stderr, "%c %s ", ll, t.utc().c_str());
|
||||
vfprintf(stderr, format, ap);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
logf_m.unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a log file for appending. If a log file is already open, then it is
|
||||
* closed and the new one is opened.
|
||||
*
|
||||
* file - file location to open
|
||||
*/
|
||||
bool Logger::open(const string& file)
|
||||
{
|
||||
close();
|
||||
logf_m.lock();
|
||||
logf = fopen(file.c_str(), "a");
|
||||
if (logf != NULL) {
|
||||
logf_m.unlock();
|
||||
return true;
|
||||
} else {
|
||||
logf_m.unlock();
|
||||
cerr_m.lock();
|
||||
cerr << "fopen() failed (" << file << "): " << strerror(errno) << '\n';
|
||||
cerr_m.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
// g++ -Wall -c thread.cpp -o thread.o
|
||||
// g++ -Wall -c mutex.cpp -o mutex.o
|
||||
// g++ -Wall -c time.cpp -o time.o
|
||||
// g++ -Wall -DUNIT_TEST -c logger.cpp -o logger.o
|
||||
// g++ -Wall -DUNIT_TEST logger.o mutex.o thread.o time.o -o logger -pthread
|
||||
int main()
|
||||
{
|
||||
Logger logger;
|
||||
|
||||
logger.open("delete.me");
|
||||
logger.set_loglevel(Logger::MINOR);
|
||||
logger.close();
|
||||
LWARNS("This should appear on stderr");
|
||||
logger.open("delete.me.also");
|
||||
LINFO("%s\n", "hey it works");
|
||||
LDEBUGS("This shouldn't be saved in the file.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // UNIT_TEST
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_LOGGER_HPP
|
||||
#define LIBSOCKTHREAD_LOGGER_HPP
|
||||
|
||||
/*
|
||||
* Some helpful macros:
|
||||
*
|
||||
* LDEBUG - debugging messages
|
||||
* LMINOR - unimportant messages
|
||||
* LINFO - informational messages
|
||||
* LWARN - errors we automatically recover from
|
||||
* LERROR - major, important errors
|
||||
*
|
||||
* These only work if your Logger object is called "logger"
|
||||
*/
|
||||
// Prints out the file name, function name, and line number before the message
|
||||
#define LDEBUG(format, ...) logger.log(Logger::DEBUG, "%s:%s:%d:" \
|
||||
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||
// This is the same as above, except it doesn't accept varargs
|
||||
#define LDEBUGS(str) logger.log(Logger::DEBUG, "%s:%s:%d:" \
|
||||
str, __FILE__, __func__, __LINE__);
|
||||
#define LMINOR(format, ...) logger.log(Logger::MINOR, "%s:%s:%d:" \
|
||||
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||
#define LMINORS(str) logger.log(Logger::MINOR, "%s:%s:%d:" \
|
||||
str, __FILE__, __func__, __LINE__);
|
||||
#define LINFO(format, ...) logger.log(Logger::INFO, "%s:%s:%d:" \
|
||||
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||
#define LINFOS(str) logger.log(Logger::INFO, "%s:%s:%d:" \
|
||||
str, __FILE__, __func__, __LINE__);
|
||||
#define LWARN(format, ...) logger.log(Logger::WARN, "%s:%s:%d:" \
|
||||
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||
#define LWARNS(str) logger.log(Logger::WARN, "%s:%s:%d:" \
|
||||
str, __FILE__, __func__, __LINE__);
|
||||
#define LERROR(format, ...) logger.log(Logger::ERROR, "%s:%s:%d:" \
|
||||
format, __FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||
#define LERRORS(str) logger.log(Logger::ERROR, "%s:%s:%d:" \
|
||||
str, __FILE__, __func__, __LINE__);
|
||||
|
||||
namespace Libsockthread {
|
||||
class Logger {
|
||||
public:
|
||||
enum priority_t {DEBUG = 0, MINOR = 1, INFO = 2, WARN = 3,
|
||||
ERROR = 4};
|
||||
|
||||
Logger()
|
||||
: logf(NULL), loglevel(Logger::DEBUG) { }
|
||||
~Logger()
|
||||
{ close(); }
|
||||
|
||||
void close();
|
||||
void log(priority_t priority, const char* format, ...);
|
||||
priority_t get_loglevel()
|
||||
{ loglevel_m.lock(); priority_t ll = loglevel;
|
||||
loglevel_m.unlock(); return ll; }
|
||||
bool open(const string& file);
|
||||
void set_loglevel(priority_t priority)
|
||||
{ loglevel_m.lock(); loglevel = priority; loglevel_m.unlock(); }
|
||||
private:
|
||||
Mutex cerr_m;
|
||||
FILE* logf;
|
||||
Mutex logf_m;
|
||||
priority_t loglevel;
|
||||
Mutex loglevel_m;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_LOGGER_HPP
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modelled after JThread by Jori Liesenborgs
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "mutex.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
/*
|
||||
* Creates a mutex
|
||||
*/
|
||||
Mutex::Mutex()
|
||||
{
|
||||
#ifdef WINTHREAD
|
||||
mutex = CreateMutex(NULL, false, NULL);
|
||||
assert(mutex != NULL);
|
||||
#else
|
||||
int rc = pthread_mutex_init(&mutex, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys a mutex
|
||||
*/
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
#ifdef WINTHREAD
|
||||
BOOL rc = CloseHandle(mutex);
|
||||
assert(rc);
|
||||
#else
|
||||
int rc = pthread_mutex_destroy(&mutex);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Locks the mutex
|
||||
*/
|
||||
void Mutex::lock()
|
||||
{
|
||||
#ifdef WINTHREAD
|
||||
DWORD rc = WaitForSingleObject(mutex, INFINITE);
|
||||
assert(rc != WAIT_FAILED);
|
||||
#else
|
||||
int rc = pthread_mutex_lock(&mutex);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlocks the mutex
|
||||
*/
|
||||
void Mutex::unlock()
|
||||
{
|
||||
#ifdef WINTHREAD
|
||||
BOOL rc = ReleaseMutex(mutex);
|
||||
assert(rc);
|
||||
#else
|
||||
int rc = pthread_mutex_unlock(&mutex);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
// g++ -Wall -c thread.cpp -o thread.o
|
||||
// g++ -Wall -DUNIT_TEST -c mutex.cpp -o mutex.o
|
||||
// g++ -Wall -DUNIT_TEST mutex.o thread.o -o mutex -pthread
|
||||
#include "thread.hpp"
|
||||
|
||||
Mutex widget;
|
||||
|
||||
int main()
|
||||
{
|
||||
class Mutex_test : public Thread
|
||||
{
|
||||
public:
|
||||
Mutex_test(int n)
|
||||
: testval(n) {}
|
||||
|
||||
void* thread()
|
||||
{
|
||||
widget.lock();
|
||||
cout << "I got it! thread #" << testval << '\n';
|
||||
// If this works, only one thread should be able to lock the
|
||||
// widget, since it is never unlocked
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int testval;
|
||||
};
|
||||
|
||||
Mutex_test t1(1);
|
||||
Mutex_test t2(2);
|
||||
Mutex_test t3(3);
|
||||
t1.start(); t2.start(); t3.start();
|
||||
while (true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // UNIT_TEST
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modelled after JThread by Jori Liesenborgs
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_MUTEX_HPP
|
||||
#define LIBSOCKTHREAD_MUTEX_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
private:
|
||||
#ifdef WINTHREAD
|
||||
HANDLE mutex;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_MUTEX_HPP
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: platform.hpp,v 1.5 2004/07/22 03:54:01 mpc Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Global includes and platform configuration. This is used to compile the
|
||||
* library, but is not intended for use by users of the library in their
|
||||
* own programs.
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_PLATFORM_HPP
|
||||
#define LIBSOCKTHREAD_PLATFORM_HPP
|
||||
|
||||
/*
|
||||
* Operating system
|
||||
*/
|
||||
#define FREEBSD 0 // FreeBSD
|
||||
#define WIN32 1 // Windows
|
||||
#define LINUX 2 // Linux
|
||||
|
||||
#if OS == WIN32
|
||||
#define WINSOCK
|
||||
#define WINTHREAD
|
||||
#endif
|
||||
|
||||
#ifndef WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#ifndef WINSOCK
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifndef WINTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdint.h> // TODO replace with Boost's version
|
||||
#include <string>
|
||||
#if defined WINSOCK || defined WINTHREAD
|
||||
#include <windows.h>
|
||||
#endif
|
||||
using namespace std;
|
||||
#include "types.hpp"
|
||||
|
||||
#endif // LIBSOCKTHREAD_PLATFORM_HPP
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: socket.cpp,v 1.8 2004/07/22 22:08:20 mpc Exp $
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "socket_error.hpp"
|
||||
#include "socket.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
/*
|
||||
* Closes the socket
|
||||
*/
|
||||
void Socket::close()
|
||||
{
|
||||
if (sock != SERR) {
|
||||
if (close(sock) == -1)
|
||||
; // FIXME log the error
|
||||
}
|
||||
sock = SERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes the address associated with the socket
|
||||
*/
|
||||
void Socket::set_addr(Socket_addr& addr)
|
||||
{
|
||||
close();
|
||||
this->addr = addr;
|
||||
setup_socket();
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepares the socket for use
|
||||
*/
|
||||
void Socket::setup_socket()
|
||||
{
|
||||
assert(sock == SERR); // the descriptor shouldn't be active
|
||||
if (!addr.is_ready())
|
||||
throw Socket_error("Couldn't create socket: address isn't ready");
|
||||
|
||||
sock = socket(addr.get_family(), addr.get_type(), 0);
|
||||
if (sock == SERR)
|
||||
throw Socket_error(strerror(errno));
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: socket.hpp,v 1.8 2004/07/22 22:08:20 mpc Exp $
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_SOCKET_HPP
|
||||
#define LIBSOCKTHREAD_SOCKET_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Socket {
|
||||
public:
|
||||
#ifdef WINSOCK
|
||||
typedef SOCKET socket_t;
|
||||
enum { SERR = SOCKET_ERROR };
|
||||
#else
|
||||
typedef int socket_t;
|
||||
enum { SERR = -1 };
|
||||
#endif
|
||||
|
||||
Socket()
|
||||
: addr(), sock(SERR) {}
|
||||
Socket(Socket_addr& addr) // throws Socket_error
|
||||
: addr(addr), sock(SERR) { setup_socket(); }
|
||||
|
||||
void close();
|
||||
size_t read(vector<uchar_t>& buf, size_t max = 0);
|
||||
size_t read_until(vector<uchar_t>& buf, uchar_t delim = '\n');
|
||||
void set_addr(Socket_addr& addr); // throws Socket_error
|
||||
void set_blocking(bool blocking);
|
||||
size_t write(vector<uchar_t>& buf);
|
||||
void write_all(vector<uchar_t>& buf);
|
||||
size_t write_until(vector<uchar_t& buf, uchar_t delim = '\n');
|
||||
private:
|
||||
void setup_socket(); // throws Socket_error
|
||||
|
||||
Socket_addr addr;
|
||||
socket_t sock;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_SOCKET_HPP
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: socket_addr.cpp,v 1.4 2004/07/22 19:10:59 mpc Exp $
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "socket_error.hpp"
|
||||
#include "socket_addr.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
Socket_addr::Socket_addr(Socket_addr& rhs)
|
||||
{
|
||||
delete[] ip;
|
||||
if (rhs.resolved) {
|
||||
if (rhs.family == AF_INET) {
|
||||
ip = new char[INET_ADDRSTRLEN];
|
||||
else
|
||||
ip = new char[INET6_ADDRSTRLEN];
|
||||
strcpy(ip, rhs.ip);
|
||||
}
|
||||
family = rhs.family;
|
||||
host = rhs.host;
|
||||
port = rhs.port;
|
||||
resolved = rhs.resolved;
|
||||
type = rhs.type;
|
||||
}
|
||||
|
||||
Socket_addr& Socket_addr::operator=(const Socket_addr& rhs)
|
||||
{
|
||||
if (this == &rhs) // check for self-assignment: a = a
|
||||
return *this;
|
||||
|
||||
delete[] ip;
|
||||
if (rhs.resolved) {
|
||||
if (rhs.family == AF_INET)
|
||||
ip = new char[INET_ADDRSTRLEN];
|
||||
else
|
||||
ip = new char[INET6_ADDRSTRLEN];
|
||||
strcpy(ip, rhs.ip);
|
||||
}
|
||||
family = rhs.family;
|
||||
host = rhs.host;
|
||||
port = rhs.port;
|
||||
type = rhs.type;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs a DNS lookup
|
||||
*/
|
||||
void Socket_addr::resolve()
|
||||
{
|
||||
resolved = false; // in case they already had a host name but just set a
|
||||
// new one with set_host()
|
||||
hostent* hent = gethostbyname(host.c_str());
|
||||
if (hent == NULL)
|
||||
throw Dns_error(hstrerror(h_errno));
|
||||
assert(hent->h_addrtype == AF_INET || hent->h_addrtype == AF_INET6);
|
||||
family = hent->h_addrtype;
|
||||
delete[] ip;
|
||||
if (family == AF_INET) {
|
||||
ip = new char[INET_ADDRSTRLEN];
|
||||
else
|
||||
ip = new char[INET6_ADDRSTRLEN];
|
||||
strcpy(ip, hent->h_addr_list[0]);
|
||||
resolved = true;
|
||||
}
|
||||
|
||||
bool Socket_addr::operator==(const Socket_addr& rhs)
|
||||
{
|
||||
if (rhs.family == family
|
||||
&& rhs.host == host
|
||||
&& strcmp(rhs.ip, ip) == 0
|
||||
&& rhs.port == port
|
||||
&& rhs.resolved == resolved
|
||||
&& rhs.type == type)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: socket_addr.hpp,v 1.4 2004/07/22 19:10:59 mpc Exp $
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_SOCKET_ADDR_HPP
|
||||
#define LIBSOCKTHREAD_SOCKET_ADDR_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Socket_addr {
|
||||
public:
|
||||
Socket_addr()
|
||||
: family(AF_INET), resolved(false) { }
|
||||
Socket_addr(Socket_addr& rhs);
|
||||
Socket_addr(int type, string& host, uint16_t port)
|
||||
: family(AF_INET), host(host), type(type), port(port)
|
||||
{ resolve(); } // throws Dns_error
|
||||
~Socket_addr()
|
||||
{ delete[] ip; }
|
||||
|
||||
int get_family() const
|
||||
{ return family; }
|
||||
const char* get_ip() const // Warning! This can be NULL!
|
||||
{ return ip; }
|
||||
uint16_t get_port() const
|
||||
{ return port; }
|
||||
int get_type() const
|
||||
{ return type;
|
||||
bool is_ready() const
|
||||
{ return resolved; }
|
||||
Socket_addr& operator=(const Socket_addr& rhs);
|
||||
bool operator==(const Socket_addr& rhs);
|
||||
void set_host(string& host) // throws Dns_error
|
||||
{ this->host = host; resolve(); }
|
||||
void set_port(uint16_t port)
|
||||
{ this->port = port; }
|
||||
void set_type(int type)
|
||||
{ this->type = type; }
|
||||
private:
|
||||
void resolve(); // throws Dns_error
|
||||
|
||||
int family; // AF_INET or AF_INET6
|
||||
string host;
|
||||
char* ip;
|
||||
uint16_t port;
|
||||
bool resolved;
|
||||
int type; // SOCK_STREAM or SOCK_DGRAM
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_SOCKET_ADDR_HPP
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "socket_connector.hpp"
|
||||
using namespace Libsockthread;
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP
|
||||
#define LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Socket_connector : public Socket {
|
||||
public:
|
||||
Socket_connector(Socket_addr& addr)
|
||||
: Socket(addr);
|
||||
|
||||
void connect();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_SOCKET_CONNECTOR_HPP
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_SOCKET_ERROR_HPP
|
||||
#define LIBSOCKTHREAD_SOCKET_ERROR_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Socket_error : public runtime_error {
|
||||
public:
|
||||
Socket_error(const string& s)
|
||||
: runtime_error(s) { }
|
||||
};
|
||||
class Dns_error : public Socket_error {
|
||||
public:
|
||||
Dns_error(const string& s)
|
||||
: Socket_error(s) { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_SOCKET_ERROR_HPP
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "socket_listener.hpp"
|
||||
using namespace Libsockthread;
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_SOCKET_LISTENER_HPP
|
||||
#define LIBSOCKTHREAD_SOCKET_LISTENER_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Socket_listener {
|
||||
public:
|
||||
Socket_listener(Socket_addr& addr)
|
||||
: Socket(addr);
|
||||
|
||||
void accept();
|
||||
void listen();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_SOCKET_LISTENER_HPP
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: The strl.c file retains its original license (at the top of strl.c)
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_STRL_H
|
||||
#define LIBSOCKTHREAD_STRL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern size_t strlcat(char *dst, const char *src, size_t siz);
|
||||
extern size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* LIBSOCKTHREAD_STRL_H */
|
@ -1,194 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modelled after JThread by Jori Liesenborgs
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "thread.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
/*
|
||||
* Gets the return value of a finished thread
|
||||
*/
|
||||
void* Thread::get_retval()
|
||||
{
|
||||
void* val;
|
||||
running_m.lock();
|
||||
if (running)
|
||||
val = NULL;
|
||||
else
|
||||
val = retval;
|
||||
running_m.unlock();
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the thread is running
|
||||
*/
|
||||
bool Thread::is_running()
|
||||
{
|
||||
running_m.lock();
|
||||
bool r = running;
|
||||
running_m.unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stops the thread
|
||||
* Generally NOT a good idea
|
||||
*/
|
||||
void Thread::kill()
|
||||
{
|
||||
running_m.lock();
|
||||
#ifndef NDEBUG
|
||||
// make sure it as actually running first
|
||||
if (!running) {
|
||||
running_m.unlock();
|
||||
assert(false);
|
||||
}
|
||||
#endif
|
||||
#ifdef WINTHREAD
|
||||
BOOL rc = TerminateThread(handle, NULL);
|
||||
assert(rc);
|
||||
#else
|
||||
int rc = pthread_cancel(id);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
running = false;
|
||||
running_m.unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts the thread
|
||||
*/
|
||||
void Thread::start()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
// check whether the thread is already running
|
||||
running_m.lock();
|
||||
assert(!running);
|
||||
running_m.unlock();
|
||||
#endif
|
||||
continue_m.lock();
|
||||
#ifdef WINTHREAD
|
||||
handle = CreateThread(NULL, 0, &the_thread, this, 0, &id);
|
||||
assert(handle != NULL);
|
||||
#else
|
||||
int rc = pthread_create(&id, 0, &the_thread, this);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
// Wait until `running' is set
|
||||
running_m.lock();
|
||||
while (!running) {
|
||||
running_m.unlock();
|
||||
running_m.lock();
|
||||
}
|
||||
running_m.unlock();
|
||||
continue_m.unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for the thread
|
||||
*/
|
||||
void* Thread::the_thread(void *param)
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(param);
|
||||
t->running_m.lock();
|
||||
t->running = true;
|
||||
t->running_m.unlock();
|
||||
// wait until we can continue
|
||||
t->continue_m.lock();
|
||||
t->continue_m.unlock();
|
||||
void* ret = t->thread();
|
||||
t->running_m.lock();
|
||||
t->running = false;
|
||||
t->retval = ret;
|
||||
t->running_m.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
// g++ -Wall -c mutex.cpp -o mutex.o
|
||||
// g++ -Wall -DUNIT_TEST -c thread.cpp -o thread.o
|
||||
// g++ -Wall -DUNIT_TEST mutex.o thread.o -o thread -pthread
|
||||
int main()
|
||||
{
|
||||
class Thread_test : public Thread
|
||||
{
|
||||
public:
|
||||
Thread_test(int testval)
|
||||
: testval(testval) { }
|
||||
|
||||
int get_testval()
|
||||
{
|
||||
testval_m.lock();
|
||||
int rc = testval;
|
||||
testval_m.unlock();
|
||||
return rc;
|
||||
}
|
||||
void *thread()
|
||||
{
|
||||
// just do something
|
||||
while (true) {
|
||||
testval_m.lock();
|
||||
++testval;
|
||||
testval_m.unlock();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int testval;
|
||||
Mutex testval_m;
|
||||
};
|
||||
|
||||
Thread_test t1(1);
|
||||
t1.start();
|
||||
Thread_test t2(1000000);
|
||||
t2.start();
|
||||
Thread_test t3(-1000000);
|
||||
t3.start();
|
||||
while (true) {
|
||||
if (t1.is_running())
|
||||
cout << "t1 is running..." << t1.get_testval() << '\n';
|
||||
if (t2.is_running())
|
||||
cout << "t2 is running..." << t2.get_testval() << '\n';
|
||||
if (t3.is_running())
|
||||
cout << "t3 is running..." << t3.get_testval() << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // UNIT_TEST
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modelled after JThread by Jori Liesenborgs
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_THREAD_HPP
|
||||
#define LIBSOCKTHREAD_THREAD_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Thread {
|
||||
public:
|
||||
Thread()
|
||||
: retval(NULL), running(false) { }
|
||||
virtual ~Thread()
|
||||
{ kill(); }
|
||||
|
||||
void* get_retval();
|
||||
bool is_running();
|
||||
void kill();
|
||||
void start();
|
||||
virtual void* thread() = 0;
|
||||
private:
|
||||
#ifdef WINTHREAD
|
||||
static DWORD WINAPI the_thread(void* param);
|
||||
HANDLE handle;
|
||||
DWORD id;
|
||||
#else
|
||||
static void* the_thread(void* param);
|
||||
pthread_t id;
|
||||
#endif
|
||||
Mutex continue_m;
|
||||
void* retval;
|
||||
bool running;
|
||||
Mutex running_m;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_THREAD_HPP
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "time.hpp"
|
||||
using namespace Libsockthread;
|
||||
|
||||
/*
|
||||
* Converts the time to an ISO 8601 standard date and time
|
||||
* Example: 2004-07-01T19:03:47Z
|
||||
*/
|
||||
string& Time::utc()
|
||||
{
|
||||
struct tm* tm = gmtime(&unixtime);
|
||||
char t[21];
|
||||
strftime(t, sizeof t, "%Y-%m-%dT%H:%M:%SZ", tm);
|
||||
return formatted = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts the time to an ISO 8601 standard date
|
||||
* Example: 2004-07-01Z
|
||||
*/
|
||||
string& Time::utc_date()
|
||||
{
|
||||
struct tm* tm = gmtime(&unixtime);
|
||||
char t[12];
|
||||
strftime(t, sizeof t, "%Y-%m-%dZ", tm);
|
||||
return formatted = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts the time to an ISO 8601 standard time
|
||||
* Example: 19:03:47Z
|
||||
*/
|
||||
string& Time::utc_time()
|
||||
{
|
||||
struct tm* tm = gmtime(&unixtime);
|
||||
char t[10];
|
||||
strftime(t, sizeof t, "%H:%M:%SZ", tm);
|
||||
return formatted = t;
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
// g++ -Wall -DUNIT_TEST time.cpp -o time
|
||||
int main()
|
||||
{
|
||||
Time t;
|
||||
cout << "Current date and time is " << t.utc() << '\n';
|
||||
cout << "Current date is " << t.utc_date() << '\n';
|
||||
cout << "Current time is " << t.utc_time() << '\n';
|
||||
cout << "Formatted time is " << t.get_formatted() << " (should be the same)\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // UNIT_TEST
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_TIME_HPP
|
||||
#define LIBSOCKTHREAD_TIME_HPP
|
||||
|
||||
namespace Libsockthread {
|
||||
class Time {
|
||||
public:
|
||||
Time()
|
||||
{ now(); }
|
||||
|
||||
string& get_formatted()
|
||||
{ return formatted; }
|
||||
void now()
|
||||
{ unixtime = time(0); }
|
||||
string& utc();
|
||||
string& utc_date();
|
||||
string& utc_time();
|
||||
private:
|
||||
string formatted;
|
||||
time_t unixtime;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LIBSOCKTHREAD_TIME_HPP
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef LIBSOCKTHREAD_TYPES_HPP
|
||||
#define LIBSOCKTHREAD_TYPES_HPP
|
||||
|
||||
/*
|
||||
* Shorten some standard variable types
|
||||
*/
|
||||
typedef signed char schar_t;
|
||||
typedef unsigned char uchar_t;
|
||||
typedef unsigned int uint_t;
|
||||
typedef unsigned long ulong_t;
|
||||
typedef unsigned short ushort_t;
|
||||
|
||||
#endif // LIBSOCKTHREAD_TYPES_HPP
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "bigint.hpp"
|
||||
|
||||
/******************************************************************************/
|
||||
// Note: All the const_casts below are necessary because libtomcrypt doesn't //
|
||||
// have its arguments as const, even when they are not changed //
|
||||
/******************************************************************************/
|
||||
|
||||
Bigint::Bigint(const Bigint& bigint)
|
||||
{
|
||||
init();
|
||||
copyover_mp_int(bigint.mpi);
|
||||
}
|
||||
|
||||
Bigint::Bigint(const uchar_t* data, size_t size)
|
||||
{
|
||||
init();
|
||||
import_uraw(data, size);
|
||||
}
|
||||
|
||||
Bigint::Bigint(uint16_t i)
|
||||
{
|
||||
init();
|
||||
i = htons(i);
|
||||
import_uraw(reinterpret_cast<uchar_t*>(&i), 2);
|
||||
}
|
||||
|
||||
Bigint::Bigint(uint32_t i)
|
||||
{
|
||||
init();
|
||||
i = htonl(i);
|
||||
import_uraw(reinterpret_cast<uchar_t*>(&i), 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces our current mp_int with another one
|
||||
* (just a wrapper for mp_copy)
|
||||
*/
|
||||
void Bigint::copyover_mp_int(const mp_int& i)
|
||||
{
|
||||
int rc = mp_copy(const_cast<mp_int*>(&i), &mpi);
|
||||
assert(rc == MP_OKAY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves a Bigint to a raw unsigned big-endian integer
|
||||
* Note that the result must be freed with delete[]
|
||||
*
|
||||
* size - filled with the size of the output
|
||||
*
|
||||
* Returns: binary data
|
||||
*/
|
||||
uchar_t* Bigint::export_uraw(size_t& size) const
|
||||
{
|
||||
uchar_t* out;
|
||||
size = mp_unsigned_bin_size(const_cast<mp_int*>(&mpi));
|
||||
if (size != 0) {
|
||||
out = new uchar_t[size];
|
||||
int rc = mp_to_unsigned_bin(const_cast<mp_int*>(&mpi), out);
|
||||
assert(rc == MP_OKAY);
|
||||
} else { // size == 0
|
||||
size = 1;
|
||||
out = new uchar_t[1];
|
||||
out[0] = 0;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads a raw unsigned big-endian integer into Bigint
|
||||
*
|
||||
* data - binary data
|
||||
* size - size of data
|
||||
*/
|
||||
void Bigint::import_uraw(const uchar_t* data, size_t size)
|
||||
{
|
||||
uchar_t tmp[size]; // mp_read_unsigned_bin() arg 2 is not const
|
||||
memcpy(tmp, data, sizeof tmp); // I'm not taking any chances
|
||||
int rc = mp_read_unsigned_bin(&mpi, tmp, sizeof tmp);
|
||||
assert(rc == MP_OKAY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialises the object
|
||||
*/
|
||||
void Bigint::init(void)
|
||||
{
|
||||
int rc = mp_init(&mpi);
|
||||
assert(rc == MP_OKAY);
|
||||
}
|
||||
|
||||
bool Bigint::operator<(const Bigint& rhs) const
|
||||
{
|
||||
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
|
||||
if (rc == MP_LT)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Bigint& Bigint::operator=(const Bigint& rhs)
|
||||
{
|
||||
if (this != &rhs) // check for self-assignment: a = a
|
||||
copyover_mp_int(rhs.mpi);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Bigint::operator==(const Bigint& rhs) const
|
||||
{
|
||||
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
|
||||
if (rc == MP_EQ)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Bigint::operator>(const Bigint& rhs) const
|
||||
{
|
||||
int rc = mp_cmp(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi));
|
||||
if (rc == MP_GT)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Xors another Bigint with this Bigint and puts the result in Bigint `result'.
|
||||
* We can't name it "xor" because that word is reserved in C++ (see Appendex C,
|
||||
* section 3.1 in TC++PL).
|
||||
*
|
||||
* rhs - the bigint to xor with
|
||||
* result - will be filled with the result of the xor
|
||||
*/
|
||||
void Bigint::x_or(const Bigint& rhs, Bigint& result) const
|
||||
{
|
||||
int rc = mp_xor(const_cast<mp_int*>(&mpi), const_cast<mp_int*>(&rhs.mpi),
|
||||
&result.mpi);
|
||||
assert(rc == MP_OKAY);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BIGINT_HPP
|
||||
#define BIGINT_HPP
|
||||
|
||||
class Bigint {
|
||||
public:
|
||||
Bigint(void) { init(); }
|
||||
Bigint(const Bigint& bigint);
|
||||
Bigint(const uchar_t* data, size_t size);
|
||||
Bigint(uint16_t i);
|
||||
Bigint(uint32_t i);
|
||||
~Bigint(void) { mp_clear(&mpi); }
|
||||
|
||||
uchar_t* export_uraw(size_t& size) const;
|
||||
const mp_int& get_mp_int(void) const { return mpi; }
|
||||
void import_uraw(const uchar_t* data, size_t size);
|
||||
bool operator<(const Bigint& rhs) const;
|
||||
Bigint& operator=(const Bigint& rhs);
|
||||
bool operator==(const Bigint& rhs) const;
|
||||
bool operator>(const Bigint& rhs) const;
|
||||
void x_or(const Bigint& rhs, Bigint& result) const;
|
||||
|
||||
protected:
|
||||
mp_int mpi;
|
||||
|
||||
private:
|
||||
void copyover_mp_int(const mp_int& i);
|
||||
void init(void);
|
||||
};
|
||||
|
||||
#endif // BIGINT_HPP
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "chk.hpp"
|
||||
|
||||
Chk::Chk(const uchar_t* plaintext, size_t size, const string& mime_type)
|
||||
: data_size(size), mime_type(mime_type)
|
||||
{
|
||||
encrypt(plaintext);
|
||||
}
|
||||
|
||||
void Chk::encrypt(const uchar_t *pt)
|
||||
{
|
||||
int rc = register_cipher(&twofish_desc);
|
||||
assert(rc != -1);
|
||||
|
||||
uchar_t key[CRYPT_KEY_SIZE], iv[CRYPT_BLOCK_SIZE];
|
||||
prng->get_bytes(key, CRYPT_KEY_SIZE);
|
||||
prng->get_bytes(iv, CRYPT_BLOCK_SIZE);
|
||||
|
||||
symmetric_CTR ctr;
|
||||
rc = ctr_start(find_cipher("twofish"), iv, key, CRYPT_KEY_SIZE, 0, &ctr);
|
||||
assert(rc == CRYPT_OK);
|
||||
|
||||
ct = new uchar_t[data_size];
|
||||
rc = ctr_encrypt(pt, ct, data_size, &ctr);
|
||||
assert(rc == CRYPT_OK);
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CHK_HPP
|
||||
#define CHK_HPP
|
||||
|
||||
class Chk {
|
||||
public:
|
||||
//Chk(const uchar_t* cypertext, size_t size);
|
||||
Chk(const uchar_t* plaintext, size_t size, const string& mime_type);
|
||||
~Chk(void) { delete[] ct; }
|
||||
|
||||
private:
|
||||
static const size_t CRYPT_BLOCK_SIZE = 16;
|
||||
static const size_t CRYPT_KEY_SIZE = 32;
|
||||
|
||||
void encrypt(const uchar_t *pt);
|
||||
|
||||
uchar_t* ct; // cyphertext
|
||||
const size_t data_size;
|
||||
const string& mime_type; // I hate mimes.
|
||||
};
|
||||
|
||||
#endif // CHK_HPP
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "bigint.hpp"
|
||||
|
||||
Config::Config(const string& file)
|
||||
: file(file)
|
||||
{
|
||||
set_defaults();
|
||||
parse();
|
||||
configf.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks up a configuration option in the table and returns a constant value.
|
||||
* This is the same as get_property() except the value returned is a constant.
|
||||
*
|
||||
* key - key to lookup
|
||||
*
|
||||
* Returns the value associated with the key
|
||||
*/
|
||||
const string& Config::get_cproperty(const string& key) const
|
||||
{
|
||||
for (cfgmap_ci i = cfgmap.begin(); i != cfgmap.end(); i++) {
|
||||
const string s = i->first;
|
||||
if (s == key)
|
||||
return i->second;
|
||||
}
|
||||
LERROR << "Tried to lookup an invalid property: " << key << '\n';
|
||||
assert(false);
|
||||
// this should never occur, it's just to silence a compiler warning
|
||||
string* s = new string;
|
||||
return *s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a property as an integer (they are all stored as strings)
|
||||
*
|
||||
* key - key to lookup
|
||||
*
|
||||
* Returns an integer of the value associated with the key
|
||||
*/
|
||||
int Config::get_iproperty(const string& key) const
|
||||
{
|
||||
for (cfgmap_ci i = cfgmap.begin(); i != cfgmap.end(); i++) {
|
||||
const string s = i->first;
|
||||
if (s == key)
|
||||
return atoi(i->second.c_str());
|
||||
}
|
||||
LERROR << "Tried to lookup an invalid property: " << key << '\n';
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks up a configuration option in the table and returns the value
|
||||
*
|
||||
* key - key to lookup
|
||||
*
|
||||
* Returns the value associated with the key
|
||||
*/
|
||||
string& Config::get_property(const string& key)
|
||||
{
|
||||
for (cfgmap_i i = cfgmap.begin(); i != cfgmap.end(); i++) {
|
||||
const string s = i->first;
|
||||
if (s == key)
|
||||
return i->second;
|
||||
}
|
||||
LERROR << "Tried to lookup an invalid property: " << key << '\n';
|
||||
assert(false);
|
||||
// this should never occur, it's just to silence a compiler warning
|
||||
string* s = new string;
|
||||
return *s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses the configuration file, replacing default values with user defined
|
||||
* values
|
||||
*/
|
||||
void Config::parse(void)
|
||||
{
|
||||
configf.open(file.c_str());
|
||||
if (!configf) {
|
||||
cerr << "Error opening configuration file (" << file.c_str() << ")\n";
|
||||
throw runtime_error("Error opening configuration file");
|
||||
}
|
||||
size_t line = 0;
|
||||
string s;
|
||||
for (getline(configf, s); configf; getline(configf, s)) {
|
||||
line++;
|
||||
if (s.size() == 0 || s[0] == '#') // blank line or comment
|
||||
continue;
|
||||
size_t eqpos = s.find("=");
|
||||
if (eqpos == string::npos) {
|
||||
cerr << "Error parsing line #" << line << " in " << file << ": "
|
||||
<< s << '\n';
|
||||
continue;
|
||||
}
|
||||
string key = s.substr(0, eqpos);
|
||||
string value = s.substr(eqpos + 1);
|
||||
//cout << "Inserting key = " << key << " value = " << value << '\n';
|
||||
cfgmap.erase(key); // erase the default value created by set_defaults()
|
||||
cfgmap.insert(make_pair(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If you (the programmer) add something to the config file you should also add
|
||||
* it here, and vice versa
|
||||
*/
|
||||
void Config::set_defaults(void)
|
||||
{
|
||||
cfgmap.insert(make_pair("samhost", "localhost"));
|
||||
cfgmap.insert(make_pair("samport", "7656"));
|
||||
cfgmap.insert(make_pair("samname", "enclave"));
|
||||
cfgmap.insert(make_pair("tunneldepth", "2"));
|
||||
cfgmap.insert(make_pair("references", "cfg/peers.ref"));
|
||||
cfgmap.insert(make_pair("loglevel", "1"));
|
||||
cfgmap.insert(make_pair("logfile", "log/enclave.log"));
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_HPP
|
||||
#define CONFIG_HPP
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config(const string& file);
|
||||
|
||||
const string& get_cproperty(const string& key) const;
|
||||
int get_iproperty(const string& key) const;
|
||||
string& get_property(const string& key);
|
||||
|
||||
private:
|
||||
typedef map<const string, string>::const_iterator cfgmap_ci;
|
||||
typedef map<const string, string>::iterator cfgmap_i;
|
||||
|
||||
void parse(void);
|
||||
void set_defaults(void);
|
||||
|
||||
ifstream configf;
|
||||
const string file;
|
||||
map<const string, string> cfgmap;
|
||||
};
|
||||
|
||||
#endif // CONFIG_HPP
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
Logger::Logger(const string& file)
|
||||
: file(file)
|
||||
{
|
||||
set_pri(debug);
|
||||
set_loglevel(static_cast<priority_t>(config->get_iproperty("loglevel")));
|
||||
logf.open(file.c_str(), ios::app);
|
||||
if (!logf) {
|
||||
cerr << "Error opening log file (" << file.c_str() << ")\n";
|
||||
throw runtime_error("Error opening log file");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN_STRERROR
|
||||
/*
|
||||
* strerror() for primitive operating systems
|
||||
*/
|
||||
TCHAR* win_strerror(TCHAR* str, size_t size)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf,
|
||||
0, NULL);
|
||||
snprintf(str, size, "%s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
return str;
|
||||
}
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LOGGER_HPP
|
||||
#define LOGGER_HPP
|
||||
|
||||
/*
|
||||
* LDEBUG - debugging messages
|
||||
* LMINOR - unimportant messages
|
||||
* LINFO - informational messages
|
||||
* LWARN - errors we automatically recover from
|
||||
* LERROR - major, important errors
|
||||
*/
|
||||
#if VERBOSE_LOGS
|
||||
#define LDEBUG logger->set_pri(Logger::debug); (*logger) << "(D)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
|
||||
#define LMINOR logger->set_pri(Logger::minor); (*logger) << "(M)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
|
||||
#define LINFO logger->set_pri(Logger::info); (*logger) << "(I)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
|
||||
#define LWARN logger->set_pri(Logger::warn); (*logger) << "(W)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
|
||||
#define LERROR logger->set_pri(Logger::error); (*logger) << "(E)" << __FILE__ << ':' << __LINE__ << ':' << __func__ << ": "
|
||||
#else
|
||||
#define LDEBUG logger->set_pri(Logger::debug); (*logger) << "(D)"
|
||||
#define LMINOR logger->set_pri(Logger::minor); (*logger) << "(M)"
|
||||
#define LINFO logger->set_pri(Logger::info); (*logger) << "(I)"
|
||||
#define LWARN logger->set_pri(Logger::warn); (*logger) << "(W)"
|
||||
#define LERROR logger->set_pri(Logger::error); (*logger) << "(E)"
|
||||
#endif
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
typedef enum {debug = 0, minor = 1, info = 2, warn = 3, error = 4}
|
||||
priority_t;
|
||||
|
||||
Logger(const string& file);
|
||||
|
||||
void flush(void) { logf.flush(); }
|
||||
priority_t get_loglevel(void) const { return loglevel; }
|
||||
void set_loglevel(priority_t priority) { loglevel = priority; }
|
||||
Logger& operator<<(char c)
|
||||
{ if (priority >= loglevel) { logf << c; flush(); } return *this; }
|
||||
Logger& operator<<(const char* c)
|
||||
{ if (priority >= loglevel) { logf << c; flush(); } return *this; }
|
||||
Logger& operator<<(int i)
|
||||
{ if (priority >= loglevel) { logf << i; flush(); } return *this; }
|
||||
Logger& operator<<(const string& s)
|
||||
{ if (priority >= loglevel) { logf << s; flush(); } return *this; }
|
||||
Logger& operator<<(unsigned int i)
|
||||
{ if (priority >= loglevel) { logf << i; flush(); } return *this; }
|
||||
void set_pri(priority_t priority) { this->priority = priority; }
|
||||
|
||||
private:
|
||||
priority_t priority; // importance of the following log message(s)
|
||||
string file;
|
||||
priority_t loglevel; // write log messsages at or above this priority
|
||||
ofstream logf;
|
||||
};
|
||||
|
||||
#ifdef WIN_STRERROR
|
||||
TCHAR* win_strerror(TCHAR* str, size_t size);
|
||||
#endif
|
||||
|
||||
#endif // LOGGER_HPP
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "main.hpp"
|
||||
|
||||
Config *config; // Configuration options
|
||||
Logger *logger; // Logging mechanism
|
||||
Random *prng; // Random number generator
|
||||
Sam *sam; // SAM connection
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2) { // put some getopts stuff in here later
|
||||
cerr << "Please specify the configuration file location.\n" \
|
||||
"e.g. 'bin/enclave cfg/enclave.cfg'\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
config = new Config(argv[1]);
|
||||
} catch (const runtime_error& x) {
|
||||
return 0;
|
||||
}
|
||||
logger = new Logger(config->get_cproperty("logfile"));
|
||||
LINFO << "Enclave DHT - Built on " << __DATE__ << ' ' << __TIME__ << '\n';
|
||||
prng = new Random;
|
||||
try {
|
||||
sam = new Sam(config->get_cproperty("samhost"),
|
||||
config->get_iproperty("samport"), config->get_cproperty("samname"),
|
||||
config->get_iproperty("tunneldepth"));
|
||||
} catch (const Sam_error& x) {
|
||||
LERROR << "SAM error: " << x.what() << '\n';
|
||||
cerr << "SAM error: " << x.what() << '\n';
|
||||
if (x.code() == SAM_SOCKET_ERROR) {
|
||||
LERROR << "Check whether you have specified the correct SAM host " \
|
||||
"and port number, and that I2P is running.\n";
|
||||
cerr << "Check whether you have specified the correct SAM host " \
|
||||
"and port number, and that\nI2P is running.\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
sam->naming_lookup();
|
||||
while (sam->get_my_dest() == "")
|
||||
sam->read_buffer(); // wait until we get our own dest back from lookup
|
||||
|
||||
sam->peers->advertise_self();
|
||||
|
||||
while (true)
|
||||
sam->read_buffer();
|
||||
|
||||
delete sam;
|
||||
delete prng;
|
||||
delete logger;
|
||||
delete config;
|
||||
return 0;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MAIN_HPP
|
||||
#define MAIN_HPP
|
||||
|
||||
// intentionally left blank
|
||||
|
||||
#endif // MAIN_HPP
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef NEAR_PEER_HPP
|
||||
#define NEAR_PEER_HPP
|
||||
|
||||
//
|
||||
// Used for finding the closest peers to a sha1
|
||||
//
|
||||
|
||||
class Near_peer {
|
||||
public:
|
||||
Near_peer(const Bigint& distance, Peer* peer)
|
||||
: distance(distance), peer(peer) {}
|
||||
|
||||
Peer* get_peer(void) const { return peer; }
|
||||
bool operator<(const Near_peer& rhs) const
|
||||
{ if (distance < rhs.distance) return true; else return false; }
|
||||
|
||||
protected:
|
||||
const Bigint distance;
|
||||
|
||||
private:
|
||||
Peer* peer;
|
||||
};
|
||||
|
||||
#endif // NEAR_PEER_HPP
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PEER_HPP
|
||||
#define PEER_HPP
|
||||
|
||||
class Peer {
|
||||
public:
|
||||
Peer(const string& dest, const Sha1& kaddr)
|
||||
: dest(dest), kaddr(kaddr), lag(-1) {}
|
||||
|
||||
const string& get_b64kaddr(void) const { return kaddr.b64hash(); }
|
||||
const uchar_t* get_binkaddr(void) const { return kaddr.binhash(); }
|
||||
const string& get_dest(void) const { return dest; }
|
||||
int get_lag(void) const { return lag; }
|
||||
const string get_sdest(void) const { return dest.substr(0, 8); }
|
||||
void set_lag(int lag) { this->lag = lag; }
|
||||
|
||||
private:
|
||||
const string dest;
|
||||
const Sha1 kaddr;
|
||||
int lag; // if -1, then it is unknown
|
||||
};
|
||||
|
||||
#endif // PEER_HPP
|
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "near_peer.hpp"
|
||||
#include "rpc.hpp"
|
||||
#include "sha1.hpp"
|
||||
#include "peers.hpp"
|
||||
|
||||
/*
|
||||
* Inform other peers of our existence and collect the destination addresses of
|
||||
* nearby peers
|
||||
*/
|
||||
void Peers::advertise_self(void)
|
||||
{
|
||||
list<Near_peer> near_peers;
|
||||
get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers);
|
||||
for (list<Near_peer>::const_iterator i = near_peers.begin();
|
||||
i != near_peers.end(); i++) {
|
||||
Rpc rpc(i->get_peer());
|
||||
rpc.find_peers(sam->get_my_sha1());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the `n' nearest peers by xoring a sha1 with a kaddr
|
||||
*
|
||||
* sha1 - sha1 to find nearness to
|
||||
* n - number of peers to find
|
||||
* near_peers - a list to put the found peers in
|
||||
*/
|
||||
void Peers::get_nearest(const Sha1& sha1, size_t n, list<Near_peer>& near_peers)
|
||||
{
|
||||
near_peers.clear(); // prevents duplicate peers in the list
|
||||
for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) {
|
||||
const Sha1& kaddr = i->first;
|
||||
Bigint distance;
|
||||
sha1.x_or(kaddr, distance);
|
||||
Near_peer np(distance, &(i->second));
|
||||
near_peers.insert(near_peers.end(), np);
|
||||
}
|
||||
near_peers.sort();
|
||||
while (near_peers.size() > n)
|
||||
near_peers.pop_back();
|
||||
}
|
||||
|
||||
Peer* Peers::get_peer_by_dest(const sam_pubkey_t dest)
|
||||
{
|
||||
const string s = dest;
|
||||
return get_peer_by_dest(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a peer by its base 64 destination address
|
||||
*
|
||||
* dest - destination
|
||||
*
|
||||
* Returns: pointer to peer, or 0 if the peer wasn't found
|
||||
*/
|
||||
Peer* Peers::get_peer_by_dest(const string& dest)
|
||||
{
|
||||
for (peersmap_i i = peersmap.begin(); i != peersmap.end(); i++) {
|
||||
Peer& tmp = i->second;
|
||||
if (tmp.get_dest() == dest)
|
||||
return &(i->second);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a peer by its Kademlia address
|
||||
*
|
||||
* kaddr - Kademlia adddress
|
||||
*
|
||||
* Returns: pointer to peer, or 0 if the peer wasn't found
|
||||
*/
|
||||
Peer* Peers::get_peer_by_kaddr(const Sha1& kaddr)
|
||||
{
|
||||
peersmap_i i = peersmap.find(kaddr);
|
||||
if (i != peersmap.end())
|
||||
return &(i->second);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads peer addresses from a file
|
||||
*/
|
||||
void Peers::load(void)
|
||||
{
|
||||
string dest;
|
||||
|
||||
ifstream peersf(file.c_str());
|
||||
if (!peersf) {
|
||||
LERROR << "Couldn't load peers reference file (" << file.c_str()
|
||||
<< ")\n";
|
||||
if (peersmap.size() > 0)
|
||||
return;
|
||||
else
|
||||
throw runtime_error("No peer references in memory");
|
||||
}
|
||||
|
||||
for (getline(peersf, dest); peersf; getline(peersf, dest))
|
||||
new_peer(dest);
|
||||
|
||||
if (peersmap.size() > 0) {
|
||||
LMINOR << peersmap.size() << " peer references in memory\n";
|
||||
} else
|
||||
throw runtime_error("No peer references in memory");
|
||||
}
|
||||
|
||||
Peer* Peers::new_peer(const sam_pubkey_t dest)
|
||||
{
|
||||
const string s = dest;
|
||||
return new_peer(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a newly discovered peer to the peers map
|
||||
*
|
||||
* dest - destination address of the peer
|
||||
*
|
||||
* Returns: pointer to the peer
|
||||
*/
|
||||
Peer* Peers::new_peer(const string& dest)
|
||||
{
|
||||
// Check the destination address
|
||||
if (!sam->valid_dest(dest)) {
|
||||
LWARN << "Bad format in peer reference: " << dest.substr(0, 8) << '\n';
|
||||
return 0;
|
||||
}
|
||||
// Never add our own peer to the peers we can connect to
|
||||
if (dest == sam->get_my_dest()) {
|
||||
LDEBUG << "Not adding my own peer reference: " << dest.substr(0, 8)
|
||||
<< '\n';
|
||||
return 0;
|
||||
}
|
||||
// Be sure that the peer is not already known to us
|
||||
Peer *peer = get_peer_by_dest(dest);
|
||||
if (peer != 0) {
|
||||
LDEBUG << "Redundant peer reference: " << dest.substr(0, 8) << '\n';
|
||||
return peer;
|
||||
}
|
||||
|
||||
// Tests passed, add it
|
||||
Sha1 sha1(dest);
|
||||
pair<peersmap_i, bool> p = peersmap.insert(
|
||||
make_pair(sha1, Peer(dest, sha1)));
|
||||
assert(p.second);
|
||||
LMINOR << "New peer reference: " << dest.substr(0, 8)
|
||||
<< " (Kaddr: " << sha1.b64hash() << ")\n";
|
||||
peer = &(p.first->second);
|
||||
return peer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves peer destinations to a file
|
||||
*
|
||||
* file - the file to save to
|
||||
*/
|
||||
void Peers::save(void)
|
||||
{
|
||||
ofstream peersf(file.c_str());
|
||||
if (!peersf) {
|
||||
LERROR << "Error opening peers reference file (" << file.c_str()
|
||||
<< ")\n";
|
||||
return;
|
||||
}
|
||||
|
||||
LDEBUG << "Saving " << peersmap.size() + 1 << " peer references\n";
|
||||
peersf << sam->get_my_dest() << '\n';
|
||||
for (peersmap_ci i = peersmap.begin(); i != peersmap.end(); i++) {
|
||||
const Peer& tmp = i->second;
|
||||
peersf << tmp.get_dest() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores data on some peers
|
||||
*
|
||||
* sha1 - the sha1 value for the data
|
||||
* data - the data
|
||||
*/
|
||||
void Peers::store(const Sha1& sha1)
|
||||
{
|
||||
list<Near_peer> near_peers;
|
||||
get_nearest(sam->get_my_sha1(), PAR_RPCS, near_peers);
|
||||
for (list<Near_peer>::const_iterator i = near_peers.begin();
|
||||
i != near_peers.end(); i++) {
|
||||
Rpc rpc(i->get_peer());
|
||||
rpc.store(sha1);
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PEERS_HPP
|
||||
#define PEERS_HPP
|
||||
|
||||
class Peers {
|
||||
public:
|
||||
static const int PAR_RPCS = 3; // The number of parallel RPCs to send
|
||||
static const int RET_REFS = 20; // The number of peer refs to return on
|
||||
// failed requests
|
||||
Peers(const string& file)
|
||||
: file(file)
|
||||
{ load(); }
|
||||
~Peers(void) { save(); }
|
||||
|
||||
void advertise_self(void);
|
||||
void get_nearest(const Sha1& sha1, size_t n,
|
||||
list<Near_peer>& near_peers);
|
||||
Peer* get_peer_by_dest(const sam_pubkey_t dest);
|
||||
Peer* get_peer_by_dest(const string& dest);
|
||||
Peer* get_peer_by_kaddr(const Sha1& kaddr);
|
||||
Peer* new_peer(const sam_pubkey_t dest);
|
||||
Peer* new_peer(const string& dest);
|
||||
void store(const Sha1& sha1);
|
||||
|
||||
private:
|
||||
typedef map<const Sha1, Peer>::const_iterator peersmap_ci;
|
||||
typedef map<const Sha1, Peer>::iterator peersmap_i;
|
||||
|
||||
void load(void);
|
||||
void save(void);
|
||||
|
||||
const string file;
|
||||
map<const Sha1, Peer> peersmap;
|
||||
};
|
||||
|
||||
#endif // PEERS_HPP
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_HPP
|
||||
#define PLATFORM_HPP
|
||||
|
||||
/*
|
||||
* Operating system
|
||||
*/
|
||||
#define FREEBSD 0 // FreeBSD (untested)
|
||||
#define MINGW 1 // Windows native (Mingw)
|
||||
#define LINUX 2 // Linux
|
||||
#define CYGWIN 3 // Cygwin
|
||||
|
||||
#if OS == MINGW
|
||||
#define NO_SSIZE_T
|
||||
#define WIN_STRERROR
|
||||
#define WINSOCK
|
||||
#define WINTHREADS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System includes
|
||||
*/
|
||||
#include <arpa/inet.h>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#ifdef WINTHREADS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef NO_SSIZE_T
|
||||
typedef signed long ssize_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define this to '1' to cause the printing of source code file and line number
|
||||
* information with each log message. Set it to '0' for simple logging.
|
||||
*/
|
||||
#define VERBOSE_LOGS 0
|
||||
|
||||
/*
|
||||
* Library includes
|
||||
*/
|
||||
#include "mycrypt.h" // LibTomCrypt
|
||||
#include "sam.h" // LibSAM
|
||||
|
||||
/*
|
||||
* Local includes
|
||||
*/
|
||||
#include "mutex.hpp" // Mutex (for thread.hpp)
|
||||
#include "thread.hpp" // Thread
|
||||
#include "logger.hpp" // Logger
|
||||
#include "config.hpp" // Config
|
||||
#include "sam_error.hpp" // for sam.hpp
|
||||
#include "bigint.hpp" // for sha1.hpp
|
||||
#include "sha1.hpp" // for peers.hpp
|
||||
#include "peer.hpp" // for peers.hpp
|
||||
#include "near_peer.hpp" // for peers.hpp
|
||||
#include "peers.hpp" // for sam.hpp
|
||||
#include "sam.hpp" // SAM
|
||||
#include "random.hpp" // Random
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
extern Config *config; // Configuration options
|
||||
extern Logger *logger; // Logging mechanism
|
||||
extern Random *prng; // Random number generator
|
||||
extern Sam *sam; // Sam connection
|
||||
|
||||
#endif // PLATFORM_HPP
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "random.hpp"
|
||||
|
||||
/*
|
||||
* Prepares the Yarrow PRNG for use
|
||||
*/
|
||||
Random::Random(void)
|
||||
{
|
||||
LMINOR << "Initalising PRNG\n";
|
||||
|
||||
int rc = yarrow_start(&prng);
|
||||
assert(rc == CRYPT_OK);
|
||||
|
||||
uchar_t entropy[ENTROPY_SIZE];
|
||||
size_t sz = rng_get_bytes(entropy, ENTROPY_SIZE, NULL);
|
||||
assert(sz == ENTROPY_SIZE);
|
||||
|
||||
rc = yarrow_add_entropy(entropy, ENTROPY_SIZE, &prng);
|
||||
assert(rc == CRYPT_OK);
|
||||
|
||||
rc = yarrow_ready(&prng);
|
||||
assert(rc == CRYPT_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets `size' random bytes from the PRNG
|
||||
*
|
||||
* random - space to fill with random bytes
|
||||
* size - size of `random'
|
||||
*/
|
||||
void Random::get_bytes(uchar_t* random, size_t size)
|
||||
{
|
||||
size_t sz = yarrow_read(random, size, &prng);
|
||||
assert(sz == size);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_HPP
|
||||
#define RANDOM_HPP
|
||||
|
||||
class Random {
|
||||
public:
|
||||
Random(void);
|
||||
|
||||
void get_bytes(uchar_t* random, size_t size);
|
||||
|
||||
private:
|
||||
static const size_t ENTROPY_SIZE = 32;
|
||||
prng_state prng;
|
||||
};
|
||||
|
||||
#endif // RNG_HPP
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "rpc.hpp"
|
||||
|
||||
// These can't be 'const' because I have to make them big-endian first
|
||||
uint16_t Rpc::VERSION = htons(1);
|
||||
uint16_t Rpc::OLDEST_GOOD_VERSION = htons(1);
|
||||
|
||||
/*
|
||||
* Requests a peer to find the addresses of the closest peers to the specified
|
||||
* sha1 and return them
|
||||
*
|
||||
* sha1 - closeness to this sha1
|
||||
*/
|
||||
void Rpc::find_peers(const Sha1& sha1)
|
||||
{
|
||||
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: FIND_PEERS\n";
|
||||
|
||||
// VERSION + command + bin sha1
|
||||
const size_t len = sizeof VERSION + 1 + Sha1::SHA1BIN_LEN;
|
||||
uchar_t buf[len];
|
||||
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
|
||||
p += sizeof VERSION;
|
||||
*p = FIND_PEERS;
|
||||
p++;
|
||||
memcpy(p, sha1.binhash(), Sha1::SHA1BIN_LEN);
|
||||
sam->send_dgram(peer->get_dest(), buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the closest peer references to a Sha1
|
||||
*
|
||||
* sha1 - sha1 to test nearness to
|
||||
*/
|
||||
void Rpc::found_peers(const Sha1& sha1)
|
||||
{
|
||||
list<Near_peer> near_peers;
|
||||
sam->peers->get_nearest(sha1, Peers::RET_REFS, near_peers);
|
||||
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: FOUND_PEERS (" << near_peers.size() << " peers)\n";
|
||||
|
||||
// VERSION + command + number of sha1s (0-255) + bin sha1s
|
||||
const size_t len = sizeof VERSION + 1 + 1 +
|
||||
(near_peers.size() * (SAM_PUBKEY_LEN - 1));
|
||||
assert(near_peers.size() <= 255);
|
||||
uchar_t buf[len];
|
||||
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
|
||||
p += sizeof VERSION;
|
||||
*p = FOUND_PEERS;
|
||||
p++;
|
||||
*p = near_peers.size();
|
||||
p++;
|
||||
for (list<Near_peer>::const_iterator i = near_peers.begin();
|
||||
i != near_peers.end(); i++) {
|
||||
const Peer* peer = i->get_peer();
|
||||
memcpy(p, peer->get_dest().c_str(), (SAM_PUBKEY_LEN - 1));
|
||||
p += SAM_PUBKEY_LEN - 1;
|
||||
}
|
||||
sam->send_dgram(peer->get_dest(), buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse incoming data and invoke the appropriate RPC
|
||||
*
|
||||
* data - the data
|
||||
* size - the size of `data'
|
||||
*/
|
||||
void Rpc::parse(const void* data, size_t size)
|
||||
{
|
||||
uint16_t his_ver;
|
||||
|
||||
memcpy(&his_ver, data, sizeof VERSION);
|
||||
if (ntohs(his_ver) < ntohs(VERSION)) {
|
||||
LMINOR << "Ignored RPC from " << peer->get_sdest() << " ["
|
||||
<< peer->get_b64kaddr() << "] using obsolete protocol version "
|
||||
<< ntohs(his_ver) << '\n';
|
||||
return;
|
||||
} else if (size <= 4) {
|
||||
LWARN << "RPC too small from " << peer->get_sdest() << " ["
|
||||
<< peer->get_b64kaddr() << "]\n";
|
||||
return;
|
||||
}
|
||||
const uchar_t* p = static_cast<const uchar_t*>(data);
|
||||
|
||||
if (p[2] == PING) { //-----------------------------------------------------
|
||||
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: PING\n";
|
||||
uint32_t ptime;
|
||||
if (size != sizeof VERSION + 1 + sizeof ptime) {
|
||||
LWARN << "Malformed PING RPC from " << peer->get_sdest()
|
||||
<< " [" << peer->get_b64kaddr() << "]\n";
|
||||
return;
|
||||
}
|
||||
p += sizeof VERSION + 1;
|
||||
memcpy(&ptime, p, sizeof ptime);
|
||||
pong(ptime); // no need to ntohl() it here because we're just copying it
|
||||
return;
|
||||
|
||||
} else if (p[2] == PONG) { //----------------------------------------------
|
||||
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: PONG\n";
|
||||
uint32_t ptime;
|
||||
if (size != sizeof VERSION + 1 + sizeof ptime) {
|
||||
LWARN << "Malformed PONG RPC from " << peer->get_sdest()
|
||||
<< " [" << peer->get_b64kaddr() << "]\n";
|
||||
return;
|
||||
}
|
||||
p += sizeof VERSION + 1;
|
||||
memcpy(&ptime, p, sizeof ptime);
|
||||
ptime = ntohl(ptime);
|
||||
uint32_t now = time(NULL);
|
||||
peer->set_lag(now - ptime);
|
||||
LDEBUG << "Lag is " << peer->get_lag() << " seconds\n";
|
||||
return;
|
||||
|
||||
} else if (p[2] == FIND_PEERS) { //----------------------------------------
|
||||
if (size != sizeof VERSION + 1 + Sha1::SHA1BIN_LEN) {
|
||||
LWARN << "Malformed FIND_PEERS RPC from " << peer->get_sdest()
|
||||
<< " [" << peer->get_b64kaddr() << "]\n";
|
||||
return;
|
||||
}
|
||||
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: FIND_PEERS\n";
|
||||
found_peers(Sha1(p + 4));
|
||||
return;
|
||||
|
||||
} else if (p[2] == FOUND_PEERS) { //---------------------------------------
|
||||
const size_t refs = p[3];
|
||||
if (size != sizeof VERSION + 1 + 1 + (refs * (SAM_PUBKEY_LEN - 1))) {
|
||||
LWARN << "Malformed FOUND_PEERS RPC from " << peer->get_sdest()
|
||||
<< " [" << peer->get_b64kaddr() << "]\n";
|
||||
return;
|
||||
}
|
||||
LDEBUG << "From: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: FOUND_PEERS (" << refs << " peers)\n";
|
||||
p += sizeof VERSION + 1 + 1;
|
||||
for (size_t i = 1; i <= refs; i++) {
|
||||
sam_pubkey_t dest;
|
||||
memcpy(dest, p, SAM_PUBKEY_LEN - 1); // - 1 == no NUL in RPC
|
||||
dest[SAM_PUBKEY_LEN - 1] = '\0';
|
||||
//LDEBUG << "Message had: " << dest << '\n';
|
||||
sam->peers->new_peer(dest);
|
||||
p += SAM_PUBKEY_LEN - 1;
|
||||
}
|
||||
return;
|
||||
|
||||
} else //------------------------------------------------------------------
|
||||
LWARN << "Unknown RPC #" << static_cast<int>(p[2]) << " from "
|
||||
<< peer->get_sdest() << " [" << peer->get_b64kaddr() << "]\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a ping to someone
|
||||
*/
|
||||
void Rpc::ping(void)
|
||||
{
|
||||
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: PING\n";
|
||||
|
||||
uint32_t now = htonl(time(NULL));
|
||||
// VERSION + command + seconds since 1970
|
||||
const size_t len = sizeof VERSION + 1 + sizeof now;
|
||||
uchar_t buf[len];
|
||||
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
|
||||
p += sizeof VERSION;
|
||||
*p = PING;
|
||||
p++;
|
||||
memcpy(p, &now, sizeof now);
|
||||
sam->send_dgram(peer->get_dest(), buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a ping reply to someone
|
||||
*
|
||||
* ptime - the time the peer sent us (we echo the same time back)
|
||||
*/
|
||||
void Rpc::pong(uint32_t ptime)
|
||||
{
|
||||
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: PONG\n";
|
||||
|
||||
// VERSION + command + pinger's seconds since 1970 echoed back
|
||||
const size_t len = sizeof VERSION + 1 + sizeof ptime;
|
||||
uchar_t buf[len];
|
||||
uchar_t* p = static_cast<uchar_t*>(memcpy(buf, &VERSION, sizeof VERSION));
|
||||
p += sizeof VERSION;
|
||||
*p = PONG;
|
||||
p++;
|
||||
memcpy(p, &ptime, sizeof ptime);
|
||||
sam->send_dgram(peer->get_dest(), buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tells a peer to store some data
|
||||
*
|
||||
* sha1 - sha1 value for the data
|
||||
* data - the data
|
||||
*/
|
||||
void Rpc::store(const Sha1& sha1)
|
||||
{
|
||||
LDEBUG << "To: " << peer->get_sdest() << " [" << peer->get_b64kaddr()
|
||||
<< "] Msg: STORE\n";
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RPC_HPP
|
||||
#define RPC_HPP
|
||||
|
||||
class Rpc {
|
||||
public:
|
||||
// The PROTOCOL version we are using
|
||||
static uint16_t VERSION;
|
||||
// The oldest version we will talk to
|
||||
static uint16_t OLDEST_GOOD_VERSION;
|
||||
// RPC identifiers (0-255)
|
||||
typedef enum {
|
||||
PING = 0,
|
||||
PONG = 1,
|
||||
FIND_PEERS = 2,
|
||||
FOUND_PEERS = 3,
|
||||
STORE = 4
|
||||
} rpc_t;
|
||||
|
||||
Rpc(Peer* peer)
|
||||
: peer(peer) {};
|
||||
|
||||
void find_peers(const Sha1& sha1);
|
||||
void parse(const void* data, size_t size);
|
||||
void ping(void);
|
||||
void store(const Sha1& sha1);
|
||||
|
||||
private:
|
||||
void found_peers(const Sha1& sha1);
|
||||
void pong(uint32_t ptime);
|
||||
|
||||
Peer* peer;
|
||||
basic_string<uchar_t> data;
|
||||
};
|
||||
|
||||
#endif // RPC_HPP
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "rpc.hpp"
|
||||
#include "sam.hpp"
|
||||
|
||||
extern "C" {
|
||||
/*
|
||||
* Assorted callbacks required by LibSAM - ugly, but it works
|
||||
*/
|
||||
static void dgramback(sam_pubkey_t dest, void* data, size_t size);
|
||||
static void diedback(void);
|
||||
static void logback(char* str);
|
||||
static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents more than one Sam object from existing in the program at a time
|
||||
* (LibSAM limitation)
|
||||
*/
|
||||
bool Sam::exists = false;
|
||||
|
||||
Sam::Sam(const string& samhost, uint16_t samport, const string& destname,
|
||||
uint_t tunneldepth)
|
||||
{
|
||||
// Only allow one Sam object to exist at a time
|
||||
assert(!exists);
|
||||
exists = true;
|
||||
|
||||
// hook up callbacks
|
||||
sam_dgramback = &dgramback;
|
||||
sam_diedback = &diedback;
|
||||
sam_logback = &logback;
|
||||
sam_namingback = &namingback;
|
||||
|
||||
// we haven't connected to SAM yet
|
||||
set_connected(false);
|
||||
|
||||
// now try to connect to SAM
|
||||
connect(samhost.c_str(), samport, destname.c_str(), tunneldepth);
|
||||
}
|
||||
|
||||
Sam::~Sam(void)
|
||||
{
|
||||
delete peers; // this must be before set_connected(false)!
|
||||
if (is_connected()) {
|
||||
sam_close();
|
||||
set_connected(false);
|
||||
}
|
||||
exists = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connects to the SAM host
|
||||
*
|
||||
* samhost - host that SAM is running on (hostname or IP address)
|
||||
* samport - port number that SAM is running own
|
||||
* destname - the destination name of this program
|
||||
* tunneldepth - how long the tunnels should be
|
||||
*/
|
||||
void Sam::connect(const char* samhost, uint16_t samport, const char* destname,
|
||||
uint_t tunneldepth)
|
||||
{
|
||||
assert(!is_connected());
|
||||
LMINOR << "Connecting to SAM as '" << destname << "'\n";
|
||||
samerr_t rc = sam_connect(samhost, samport, destname, SAM_DGRAM, tunneldepth);
|
||||
if (rc == SAM_OK)
|
||||
set_connected(true);
|
||||
else
|
||||
throw Sam_error(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads peer references from disk
|
||||
* Note: this can only be called after my_dest has been set
|
||||
*/
|
||||
void Sam::load_peers(void)
|
||||
{
|
||||
peers = new Peers(config->get_cproperty("references"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts `name' to a base 64 destination
|
||||
*
|
||||
* name - name to lookup
|
||||
*/
|
||||
void Sam::naming_lookup(const string& name) const
|
||||
{
|
||||
assert(is_connected());
|
||||
sam_naming_lookup(name.c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses an incoming datagram
|
||||
*
|
||||
* dest - source destination address
|
||||
* data - datagram payload
|
||||
* size - size of `data'
|
||||
*/
|
||||
void Sam::parse_dgram(const string& dest, void* data, size_t size)
|
||||
{
|
||||
assert(is_connected());
|
||||
Peer* peer = peers->new_peer(dest);
|
||||
Rpc rpc(peer);
|
||||
rpc.parse(data, size);
|
||||
rpc.ping();
|
||||
free(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the SAM connection for incoming commands and invokes callbacks
|
||||
*/
|
||||
void Sam::read_buffer(void)
|
||||
{
|
||||
assert(is_connected());
|
||||
sam_read_buffer();
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a datagram to a destination
|
||||
*
|
||||
* dest - destination to send to
|
||||
* data - data to send
|
||||
* size - size of `data'
|
||||
*/
|
||||
void Sam::send_dgram(const string& dest, uchar_t *data, size_t size)
|
||||
{
|
||||
assert(is_connected());
|
||||
samerr_t rc = sam_dgram_send(dest.c_str(), data, size);
|
||||
assert(rc == SAM_OK); // i.e. not SAM_TOO_BIG
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the connection status
|
||||
*
|
||||
* connected - true for connected, false for disconnected
|
||||
*/
|
||||
void Sam::set_connected(bool connected)
|
||||
{
|
||||
if (!connected)
|
||||
my_dest = "";
|
||||
this->connected = connected;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets my destination address
|
||||
*
|
||||
* pubkey - the base 64 destination
|
||||
*/
|
||||
void Sam::set_my_dest(const sam_pubkey_t pubkey)
|
||||
{
|
||||
my_dest = pubkey;
|
||||
my_sha1 = Sha1(my_dest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the destination specified is of a valid base 64 syntax
|
||||
*
|
||||
* Returns: true if it is valid, false if it isn't
|
||||
*/
|
||||
bool Sam::valid_dest(const string& dest)
|
||||
{
|
||||
if (dest.size() != 516)
|
||||
return false;
|
||||
if (dest.substr(512, 4) == "AAAA") // Note this AAAA signifies a null
|
||||
return true; // certificate and doesn't actually have
|
||||
else // any bearing on validity, but we'll
|
||||
return false; // keep this check here for now anyway
|
||||
}
|
||||
|
||||
/*
|
||||
* * * * Callbacks * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Unfortunately these aren't part of the "Sam" object because they are function
|
||||
* pointers to _C_ functions. As a hack, we just have them call the global Sam
|
||||
* object.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Callback: A datagram was received
|
||||
*/
|
||||
static void dgramback(sam_pubkey_t dest, void* data, size_t size)
|
||||
{
|
||||
sam->parse_dgram(dest, data, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback: The connection to SAM has failed
|
||||
*/
|
||||
static void diedback(void)
|
||||
{
|
||||
LERROR << "Connection to SAM lost!\n";
|
||||
sam->set_connected(false);
|
||||
throw Sam_error(SAM_SOCKET_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback: A log message has been sent from LibSAM
|
||||
*/
|
||||
static void logback(char* str)
|
||||
{
|
||||
LINFO << "LibSAM: " << str << '\n';
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback: A naming lookup has completed
|
||||
*/
|
||||
static void namingback(char* name, sam_pubkey_t pubkey, samerr_t result)
|
||||
{
|
||||
Sam_error res(result);
|
||||
if (res.code() == SAM_OK) {
|
||||
if (strcmp(name, "ME") == 0) {
|
||||
sam->set_my_dest(pubkey);
|
||||
sam->load_peers();
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
} else {
|
||||
LERROR << "Naming look failed for '" << name << "': " << res.what()
|
||||
<< '\n';
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SAM_HPP
|
||||
#define SAM_HPP
|
||||
|
||||
class Sam {
|
||||
public:
|
||||
Sam(const string& samhost, uint16_t samport, const string& destname,
|
||||
uint_t tunneldepth);
|
||||
~Sam(void);
|
||||
|
||||
const string& get_my_dest(void) const { return my_dest; }
|
||||
const Sha1& get_my_sha1(void) const { return my_sha1; }
|
||||
void naming_lookup(const string& name = "ME") const;
|
||||
void read_buffer(void);
|
||||
void send_dgram(const string& dest, uchar_t *data, size_t size);
|
||||
bool valid_dest(const string& dest);
|
||||
|
||||
Peers* peers;
|
||||
|
||||
//callback-private:
|
||||
void load_peers(void);
|
||||
void parse_dgram(const string& dest, void* data, size_t size);
|
||||
void set_connected(bool connected);
|
||||
void set_my_dest(const sam_pubkey_t pubkey);
|
||||
|
||||
private:
|
||||
void connect(const char* samhost, uint16_t samport,
|
||||
const char* destname, uint_t tunneldepth);
|
||||
bool is_connected(void) const { return connected; }
|
||||
|
||||
bool connected;
|
||||
static bool exists;
|
||||
string my_dest;
|
||||
Sha1 my_sha1;
|
||||
};
|
||||
|
||||
#endif // SAM_HPP
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SAM_ERROR_HPP
|
||||
#define SAM_ERROR_HPP
|
||||
|
||||
class Sam_error {
|
||||
public:
|
||||
Sam_error(samerr_t error)
|
||||
: errcode(error) {}
|
||||
|
||||
samerr_t code(void) const { return errcode; }
|
||||
const char* what(void) const { return sam_strerror(errcode); }
|
||||
|
||||
private:
|
||||
const samerr_t errcode;
|
||||
};
|
||||
|
||||
#endif // SAM_ERROR_HPP
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "platform.hpp"
|
||||
#include "sha1.hpp"
|
||||
|
||||
Sha1::Sha1(void)
|
||||
{
|
||||
b64hashed = "No value!";
|
||||
memset(binhashed, 0, sizeof binhashed);
|
||||
}
|
||||
|
||||
Sha1::Sha1(const string& data)
|
||||
{
|
||||
/* Hash it */
|
||||
hash_state md;
|
||||
sha1_init(&md);
|
||||
int rc = sha1_process(&md, reinterpret_cast<const uchar_t*>(data.c_str()),
|
||||
data.size());
|
||||
assert(rc == CRYPT_OK);
|
||||
rc = sha1_done(&md, binhashed);
|
||||
assert(rc == CRYPT_OK);
|
||||
b64();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialises the Sha1 object from a binary hash
|
||||
*/
|
||||
Sha1::Sha1(const uchar_t binary[SHA1BIN_LEN])
|
||||
{
|
||||
memcpy(binhashed, binary, sizeof binhashed);
|
||||
b64();
|
||||
}
|
||||
|
||||
/*
|
||||
* Base 64 the binary hash
|
||||
*/
|
||||
void Sha1::b64(void)
|
||||
{
|
||||
ulong_t outlen = 29;
|
||||
char tmp[outlen];
|
||||
// b64 FIXME: replace + with ~, and / with - to be like freenet
|
||||
int rc = base64_encode(binhashed, sizeof binhashed, reinterpret_cast<uchar_t*>(tmp), &outlen);
|
||||
assert(rc == CRYPT_OK);
|
||||
b64hashed = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares two Sha1s, returning true if the this one is less than the right one
|
||||
*/
|
||||
bool Sha1::operator<(const Sha1& rhs) const
|
||||
{
|
||||
Bigint lhsnum(binhashed, SHA1BIN_LEN);
|
||||
Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN);
|
||||
if (lhsnum < rhsnum)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assigns a value from another Sha1 to this one
|
||||
*/
|
||||
Sha1& Sha1::operator=(const Sha1& rhs)
|
||||
{
|
||||
if (this != &rhs) { // check for self-assignment: a = a
|
||||
b64hashed = rhs.b64hash();
|
||||
memcpy(binhashed, rhs.binhash(), sizeof binhashed);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares Sha1s for equality
|
||||
*/
|
||||
bool Sha1::operator==(const Sha1& rhs) const
|
||||
{
|
||||
if (memcmp(binhashed, rhs.binhash(), sizeof binhashed) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Xors this Sha1 with another, and stores the result in a Bigint
|
||||
*
|
||||
* rhs - sha1 to xor this one with
|
||||
* result - will be filled with the result
|
||||
*/
|
||||
void Sha1::x_or(const Sha1& rhs, Bigint& result) const
|
||||
{
|
||||
Bigint lhsnum(binhashed, SHA1BIN_LEN);
|
||||
Bigint rhsnum(rhs.binhash(), SHA1BIN_LEN);
|
||||
lhsnum.x_or(rhsnum, result);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the author nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SHA1_HPP
|
||||
#define SHA1_HPP
|
||||
|
||||
class Sha1 {
|
||||
public:
|
||||
static const size_t SHA1BIN_LEN = 20;
|
||||
|
||||
Sha1(void);
|
||||
Sha1(const string& data);
|
||||
Sha1(const uchar_t binary[SHA1BIN_LEN]);
|
||||
|
||||
const string& b64hash(void) const { return b64hashed; }
|
||||
const uchar_t* binhash(void) const { return binhashed; }
|
||||
bool operator<(const Sha1& rhs) const;
|
||||
Sha1& operator=(const Sha1& rhs);
|
||||
bool operator==(const Sha1& rhs) const;
|
||||
void x_or(const Sha1& rhs, Bigint& result) const;
|
||||
|
||||
private:
|
||||
void b64(void);
|
||||
|
||||
string b64hashed; // base 64 of the hash
|
||||
uchar_t binhashed[SHA1BIN_LEN]; // non-NUL terminated binary hash
|
||||
};
|
||||
|
||||
#endif // SHA1_HPP
|
@ -4,6 +4,7 @@
|
||||
<target name="build" depends="builddep, jar" />
|
||||
<target name="builddep">
|
||||
<ant dir="../../ministreaming/java/" target="build" />
|
||||
<ant dir="../../jetty/" target="build" />
|
||||
<!-- ministreaming will build core -->
|
||||
</target>
|
||||
<target name="compile">
|
||||
@ -15,7 +16,7 @@
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<target name="jar" depends="builddep, compile">
|
||||
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="net.i2p.i2ptunnel.I2PTunnel" />
|
||||
|
@ -17,6 +17,8 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
@ -118,7 +120,16 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
return getSocketManager(getTunnel());
|
||||
}
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
|
||||
if (socketManager == null) {
|
||||
if (socketManager != null) {
|
||||
I2PSession s = socketManager.getSession();
|
||||
if ( (s == null) || (s.isClosed()) ) {
|
||||
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
|
||||
socketManager = buildSocketManager(tunnel);
|
||||
} else {
|
||||
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
|
||||
}
|
||||
} else {
|
||||
_log.info("Building a new socket manager since there is no other one");
|
||||
socketManager = buildSocketManager(tunnel);
|
||||
}
|
||||
return socketManager;
|
||||
@ -277,7 +288,10 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getTunnel().removeSession(sockMgr.getSession());
|
||||
I2PSession session = sockMgr.getSession();
|
||||
if (session != null) {
|
||||
getTunnel().removeSession(session);
|
||||
}
|
||||
l.log("Closing client " + toString());
|
||||
try {
|
||||
if (ss != null) ss.close();
|
||||
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
@ -48,6 +49,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
private List proxyList;
|
||||
|
||||
private HashMap addressHelpers = new HashMap();
|
||||
|
||||
private final static byte[] ERR_REQUEST_DENIED =
|
||||
("HTTP/1.1 403 Access Denied\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
@ -135,8 +138,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
return null;
|
||||
}
|
||||
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
|
||||
if (index >= size) index = size - 1;
|
||||
if (index < 0) return null;
|
||||
String proxy = (String)proxyList.get(index);
|
||||
return proxy;
|
||||
}
|
||||
@ -196,6 +197,34 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
if (host.toLowerCase().endsWith(".i2p")) {
|
||||
destination = host;
|
||||
host = getHostName(destination);
|
||||
if ( (host != null) && ("i2p".equals(host)) ) {
|
||||
int pos2;
|
||||
if ((pos2 = line.indexOf("?")) != -1) {
|
||||
// Try to find an address helper in the fragments
|
||||
String fragments = line.substring(pos2 + 1);
|
||||
pos2 = fragments.indexOf(" ");
|
||||
fragments = fragments.substring(0, pos2);
|
||||
fragments = fragments + "&";
|
||||
String fragment;
|
||||
while(fragments.length() > 0) {
|
||||
pos2 = fragments.indexOf("&");
|
||||
fragment = fragments.substring(0, pos2);
|
||||
fragments = fragments.substring(pos2 + 1);
|
||||
if (fragment.startsWith("i2paddresshelper")) {
|
||||
pos2 = fragment.indexOf("=");
|
||||
if (pos2 >= 0) {
|
||||
addressHelpers.put(destination,fragment.substring(pos2 + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String addressHelper = (String) addressHelpers.get(destination);
|
||||
if (addressHelper != null) {
|
||||
destination = addressHelper;
|
||||
host = getHostName(destination);
|
||||
}
|
||||
}
|
||||
line = method + " " + request.substring(pos);
|
||||
} else if (host.indexOf(".") != -1) {
|
||||
// The request must be forwarded to a WWW proxy
|
||||
@ -252,6 +281,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
line = "Host: " + host;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix(requestId) + "Setting host = " + host);
|
||||
} else if (line.startsWith("User-Agent: ")) {
|
||||
line = "User-Agent: MYOB/6.66 (AN/ON)";
|
||||
} else if (line.startsWith("Referer: ")) {
|
||||
// Shouldn't we be more specific, like accepting in-site referers ?
|
||||
line = "Referer: i2p";
|
||||
} else if (line.startsWith("Via: ")) {
|
||||
line = "Via: i2p";
|
||||
} else if (line.startsWith("From: ")) {
|
||||
line = "From: i2p";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,8 +190,8 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
|
||||
} catch (IOException ex) {
|
||||
if (!finished)
|
||||
_log.error("Error forwarding", ex);
|
||||
else
|
||||
_log.warn("You may ignore this", ex);
|
||||
//else
|
||||
// _log.warn("You may ignore this", ex);
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
|
@ -8,6 +8,7 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
@ -28,6 +29,7 @@ public class TunnelController implements Logging {
|
||||
private Properties _config;
|
||||
private I2PTunnel _tunnel;
|
||||
private List _messages;
|
||||
private List _sessions;
|
||||
private boolean _running;
|
||||
|
||||
/**
|
||||
@ -102,6 +104,14 @@ public class TunnelController implements Logging {
|
||||
*
|
||||
*/
|
||||
public void startTunnel() {
|
||||
try {
|
||||
doStartTunnel();
|
||||
} catch (Exception e) {
|
||||
_log.error("Error starting up the tunnel", e);
|
||||
log("Error starting up the tunnel - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
private void doStartTunnel() {
|
||||
if (_running) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Already running");
|
||||
@ -121,7 +131,7 @@ public class TunnelController implements Logging {
|
||||
} else if ("server".equals(type)) {
|
||||
startServer();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Cannot start tunnel - unknown type [" + type + "]");
|
||||
}
|
||||
}
|
||||
@ -136,9 +146,42 @@ public class TunnelController implements Logging {
|
||||
_tunnel.runHttpClient(new String[] { listenPort }, this);
|
||||
else
|
||||
_tunnel.runHttpClient(new String[] { listenPort, proxyList }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that we are using some sessions, so that they dont get
|
||||
* closed by some other tunnels
|
||||
*/
|
||||
private void acquire() {
|
||||
List sessions = _tunnel.getSessions();
|
||||
if (sessions != null) {
|
||||
for (int i = 0; i < sessions.size(); i++) {
|
||||
I2PSession session = (I2PSession)sessions.get(i);
|
||||
TunnelControllerGroup.getInstance().acquire(this, session);
|
||||
}
|
||||
_sessions = sessions;
|
||||
} else {
|
||||
_log.error("No sessions to acquire?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that we are no longer using some sessions, and if
|
||||
* no other tunnels are using them, close them.
|
||||
*/
|
||||
private void release() {
|
||||
if (_sessions != null) {
|
||||
for (int i = 0; i < _sessions.size(); i++) {
|
||||
I2PSession s = (I2PSession)_sessions.get(i);
|
||||
TunnelControllerGroup.getInstance().release(this, s);
|
||||
}
|
||||
} else {
|
||||
_log.error("No sessions to release?");
|
||||
}
|
||||
}
|
||||
|
||||
private void startClient() {
|
||||
setI2CPOptions();
|
||||
setSessionOptions();
|
||||
@ -146,6 +189,7 @@ public class TunnelController implements Logging {
|
||||
String listenPort = getListenPort();
|
||||
String dest = getTargetDestination();
|
||||
_tunnel.runClient(new String[] { listenPort, dest }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
@ -156,6 +200,7 @@ public class TunnelController implements Logging {
|
||||
String targetPort = getTargetPort();
|
||||
String privKeyFile = getPrivKeyFile();
|
||||
_tunnel.runServer(new String[] { targetHost, targetPort, privKeyFile }, this);
|
||||
acquire();
|
||||
_running = true;
|
||||
}
|
||||
|
||||
@ -193,6 +238,7 @@ public class TunnelController implements Logging {
|
||||
|
||||
public void stopTunnel() {
|
||||
_tunnel.runClose(new String[] { "forced", "all" }, this);
|
||||
release();
|
||||
_running = false;
|
||||
}
|
||||
|
||||
@ -326,14 +372,21 @@ public class TunnelController implements Logging {
|
||||
Destination dest = session.getMyDestination();
|
||||
if (dest != null) {
|
||||
buf.append("Destination hash: ").append(dest.calculateHash().toBase64()).append("<br />\n");
|
||||
buf.append("Full destination: ");
|
||||
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
|
||||
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
|
||||
if ("server".equals(getType())) {
|
||||
buf.append(" Give that out to people so they can view your service.");
|
||||
buf.append(" If you are going to share it on irc, be sure to split it on two lines");
|
||||
buf.append("Full destination: ");
|
||||
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
|
||||
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");
|
||||
long val = new Random().nextLong();
|
||||
if (val < 0) val = 0 - val;
|
||||
buf.append("<br />You can <a href=\"http://temp").append(val);
|
||||
buf.append(".i2p/?i2paddresshelper=").append(dest.toBase64()).append("\">view</a>");
|
||||
buf.append(" it in a browser (only when you're using the eepProxy)\n");
|
||||
buf.append("<br />If you are going to share this on IRC, you need to split it up:<br />\n");
|
||||
String str = dest.toBase64();
|
||||
buf.append(str.substring(0, str.length()/2)).append("<br />\n");
|
||||
buf.append(str.substring(str.length()/2)).append("<br />\n");
|
||||
buf.append("You can also post it to <a href=\"http://forum.i2p/viewforum.php?f=16\">Eepsite announcement forum</a><br />");
|
||||
}
|
||||
buf.append("<br />\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,18 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -30,29 +35,33 @@ public class TunnelControllerGroup {
|
||||
private List _controllers;
|
||||
private String _configFile = DEFAULT_CONFIG_FILE;
|
||||
|
||||
public static TunnelControllerGroup getInstance() {
|
||||
synchronized (TunnelControllerGroup.class) {
|
||||
if (_instance == null)
|
||||
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Map of I2PSession to a Set of TunnelController objects
|
||||
* using the session (to prevent closing the session until
|
||||
* no more tunnels are using it)
|
||||
*
|
||||
*/
|
||||
private Map _sessions;
|
||||
|
||||
public static TunnelControllerGroup getInstance() { return _instance; }
|
||||
|
||||
private TunnelControllerGroup(String configFile) {
|
||||
private TunnelControllerGroup(String configFile) {
|
||||
_log = I2PAppContext.getGlobalContext().logManager().getLog(TunnelControllerGroup.class);
|
||||
_instance = this;
|
||||
_controllers = new ArrayList();
|
||||
_configFile = configFile;
|
||||
_sessions = new HashMap(4);
|
||||
loadControllers(_configFile);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String args[]) {
|
||||
if ( (args == null) || (args.length <= 0) ) {
|
||||
_instance = getInstance();
|
||||
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
} else if (args.length == 1) {
|
||||
if (DEFAULT_CONFIG_FILE.equals(args[0]))
|
||||
_instance = getInstance();
|
||||
new TunnelControllerGroup(DEFAULT_CONFIG_FILE);
|
||||
else
|
||||
_instance = new TunnelControllerGroup(args[0]);
|
||||
new TunnelControllerGroup(args[0]);
|
||||
} else {
|
||||
System.err.println("Usage: TunnelControllerGroup [filename]");
|
||||
return;
|
||||
@ -287,4 +296,61 @@ public class TunnelControllerGroup {
|
||||
*/
|
||||
public List getControllers() { return _controllers; }
|
||||
|
||||
|
||||
/**
|
||||
* Note the fact that the controller is using the session so that
|
||||
* it isn't destroyed prematurely.
|
||||
*
|
||||
*/
|
||||
void acquire(TunnelController controller, I2PSession session) {
|
||||
synchronized (_sessions) {
|
||||
Set owners = (Set)_sessions.get(session);
|
||||
if (owners == null) {
|
||||
owners = new HashSet(1);
|
||||
_sessions.put(session, owners);
|
||||
}
|
||||
owners.add(controller);
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Acquiring session " + session + " for " + controller);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Note the fact that the controller is no longer using the session, and if
|
||||
* no other controllers are using it, destroy the session.
|
||||
*
|
||||
*/
|
||||
void release(TunnelController controller, I2PSession session) {
|
||||
boolean shouldClose = false;
|
||||
synchronized (_sessions) {
|
||||
Set owners = (Set)_sessions.get(session);
|
||||
if (owners != null) {
|
||||
owners.remove(controller);
|
||||
if (owners.size() <= 0) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("After releasing session " + session + " by " + controller + ", no more owners remain");
|
||||
shouldClose = true;
|
||||
_sessions.remove(session);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("After releasing session " + session + " by " + controller + ", " + owners.size() + " owners remain");
|
||||
shouldClose = false;
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("After releasing session " + session + " by " + controller + ", no owners were even known?!");
|
||||
shouldClose = true;
|
||||
}
|
||||
}
|
||||
if (shouldClose) {
|
||||
try {
|
||||
session.destroySession();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Session destroyed: " + session);
|
||||
} catch (I2PSessionException ise) {
|
||||
_log.error("Error closing the client session", ise);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import java.util.Random;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Uuuugly... generate the edit/add forms for the various
|
||||
* Uuuugly code to generate the edit/add forms for the various
|
||||
* I2PTunnel types (httpclient/client/server)
|
||||
*
|
||||
*/
|
||||
|
@ -47,9 +47,13 @@ public class WebStatusPageHelper {
|
||||
}
|
||||
|
||||
public String getSummaryList() {
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
StringBuffer buf = new StringBuffer(4*1024);
|
||||
buf.append("<ul>");
|
||||
List tunnels = TunnelControllerGroup.getInstance().getControllers();
|
||||
List tunnels = group.getControllers();
|
||||
for (int i = 0; i < tunnels.size(); i++) {
|
||||
buf.append("<li>\n");
|
||||
getSummary(buf, i, (TunnelController)tunnels.get(i));
|
||||
@ -92,24 +96,45 @@ public class WebStatusPageHelper {
|
||||
return "Action <i>" + _action + "</i> unknown";
|
||||
}
|
||||
private String stopAll() {
|
||||
List msgs = TunnelControllerGroup.getInstance().stopAllControllers();
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
List msgs = group.stopAllControllers();
|
||||
return getMessages(msgs);
|
||||
}
|
||||
private String startAll() {
|
||||
List msgs = TunnelControllerGroup.getInstance().startAllControllers();
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
List msgs = group.startAllControllers();
|
||||
return getMessages(msgs);
|
||||
}
|
||||
private String restartAll() {
|
||||
List msgs = TunnelControllerGroup.getInstance().restartAllControllers();
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
List msgs = group.restartAllControllers();
|
||||
return getMessages(msgs);
|
||||
}
|
||||
private String reloadConfig() {
|
||||
TunnelControllerGroup.getInstance().reloadControllers();
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
group.reloadControllers();
|
||||
return "Config reloaded";
|
||||
}
|
||||
private String start() {
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
if (_controllerNum < 0) return "Invalid tunnel";
|
||||
List controllers = TunnelControllerGroup.getInstance().getControllers();
|
||||
|
||||
List controllers = group.getControllers();
|
||||
if (_controllerNum >= controllers.size()) return "Invalid tunnel";
|
||||
TunnelController controller = (TunnelController)controllers.get(_controllerNum);
|
||||
controller.startTunnel();
|
||||
@ -117,8 +142,13 @@ public class WebStatusPageHelper {
|
||||
}
|
||||
|
||||
private String stop() {
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "<b>I2PTunnel instances not yet started - please be patient</b>\n";
|
||||
|
||||
if (_controllerNum < 0) return "Invalid tunnel";
|
||||
List controllers = TunnelControllerGroup.getInstance().getControllers();
|
||||
|
||||
List controllers = group.getControllers();
|
||||
if (_controllerNum >= controllers.size()) return "Invalid tunnel";
|
||||
TunnelController controller = (TunnelController)controllers.get(_controllerNum);
|
||||
controller.stopTunnel();
|
||||
@ -126,7 +156,11 @@ public class WebStatusPageHelper {
|
||||
}
|
||||
|
||||
private String getMessages() {
|
||||
return getMessages(TunnelControllerGroup.getInstance().clearAllMessages());
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
return "";
|
||||
|
||||
return getMessages(group.clearAllMessages());
|
||||
}
|
||||
|
||||
private String getMessages(List msgs) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.WebStatusPageHelper" id="helper" scope="request" />
|
||||
<jsp:setProperty name="helper" property="*" />
|
||||
<h2>Messages since last page load:</h2>
|
||||
<b><jsp:getProperty name="helper" property="actionResults" /></b>
|
||||
|
||||
<jsp:getProperty name="helper" property="summaryList" />
|
||||
|
@ -76,7 +76,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
_socketId = ++__socketId;
|
||||
local = mgr.getSession().getMyDestination();
|
||||
String us = mgr.getSession().getMyDestination().calculateHash().toBase64().substring(0,4);
|
||||
String name = us + (outgoing ? "->" : "<-") + peer.calculateHash().toBase64().subSequence(0,4);
|
||||
String name = us + (outgoing ? "->" : "<-") + peer.calculateHash().toBase64().substring(0,4);
|
||||
in = new I2PInputStream(name + " in");
|
||||
I2PInputStream pin = new I2PInputStream(name + " out");
|
||||
out = new I2POutputStream(pin);
|
||||
@ -234,7 +234,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the socket from the I2P side, e. g. by a close packet.
|
||||
* Close the socket from the I2P side (by a close packet)
|
||||
*/
|
||||
protected void internalClose() {
|
||||
synchronized (flagLock) {
|
||||
|
@ -176,7 +176,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
_log.warn(getName() + ": No socket responsible for ACK packet");
|
||||
_log.warn(getName() + ": No socket responsible for ACK packet for id " + getReadableForm(id));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,7 +223,8 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s = (I2PSocketImpl) _outSockets.get(id);
|
||||
}
|
||||
|
||||
_log.debug(getName() + ": *Disconnect outgoing for socket " + s);
|
||||
_log.debug(getName() + ": *Disconnect outgoing for socket " + s + " on id "
|
||||
+ getReadableForm(id));
|
||||
try {
|
||||
if (s != null) {
|
||||
if (payload.length > 0) {
|
||||
@ -259,7 +260,8 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
|
||||
// packet send outgoing
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket " + s);
|
||||
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket "
|
||||
+ s + " on id " + getReadableForm(id));
|
||||
if (s != null) {
|
||||
s.queueData(payload);
|
||||
return;
|
||||
@ -293,7 +295,8 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s.setRemoteID(id);
|
||||
}
|
||||
}
|
||||
_log.debug(getName() + ": *Syn! for socket " + s);
|
||||
_log.debug(getName() + ": *Syn! for socket " + s + " on id " + getReadableForm(newLocalID)
|
||||
+ " from " + d.calculateHash().toBase64().substring(0,6));
|
||||
|
||||
if (!acceptConnections) {
|
||||
// The app did not instantiate an I2PServerSocket
|
||||
@ -454,6 +457,10 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s = new I2PSocketImpl(peer, this, true, localID);
|
||||
_outSockets.put(localID, s);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": connect(" + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ ", ...): localID = " + lcID);
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
|
||||
_session.getMyDestination().writeBytes(pubkey);
|
||||
@ -462,18 +469,30 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
boolean sent = false;
|
||||
sent = _session.sendMessage(peer, packet);
|
||||
if (!sent) {
|
||||
_log.info(getName() + ": Unable to send & receive ack for SYN packet for socket " + s);
|
||||
_log.info(getName() + ": Unable to send & receive ack for SYN packet for socket "
|
||||
+ s + " with localID = " + lcID);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
|
||||
throw new I2PException("Error sending through I2P network");
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": syn sent ok to "
|
||||
+ peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " with localID = " + lcID);
|
||||
}
|
||||
if (options != null)
|
||||
remoteID = s.getRemoteID(true, options.getConnectTimeout());
|
||||
else
|
||||
remoteID = s.getRemoteID(true, getDefaultOptions().getConnectTimeout());
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": remoteID received from "
|
||||
+ peer.calculateHash().toBase64().substring(0,6)
|
||||
+ ": " + getReadableForm(remoteID)
|
||||
+ " with localID = " + lcID);
|
||||
|
||||
if (remoteID == null) {
|
||||
_context.statManager().addRateData("streaming.nackReceived", 1, 1);
|
||||
throw new ConnectException("Connection refused by peer for socket " + s);
|
||||
@ -490,7 +509,8 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
} catch (InterruptedIOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error(getName() + ": Timeout waiting for ack from syn for id "
|
||||
+ getReadableForm(lcID) + " for socket " + s, ioe);
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, ioe);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@ -498,14 +518,24 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
|
||||
throw new InterruptedIOException("Timeout waiting for ack");
|
||||
} catch (ConnectException ex) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": Connection error waiting for ack from syn for id "
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, ex);
|
||||
s.internalClose();
|
||||
throw ex;
|
||||
} catch (NoRouteToHostException ex) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": No route to host waiting for ack from syn for id "
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, ex);
|
||||
s.internalClose();
|
||||
throw ex;
|
||||
} catch (IOException ex) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
_log.error(getName() + ": Error sending syn on id "
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@ -513,7 +543,9 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
throw new I2PException("Unhandled IOException occurred");
|
||||
} catch (I2PException ex) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
_log.info(getName() + ": Error sending syn on id "
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@ -521,7 +553,9 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
throw ex;
|
||||
} catch (Exception e) {
|
||||
s.internalClose();
|
||||
_log.error(getName() + ": Unhandled error connecting", e);
|
||||
_log.error(getName() + ": Unhandled error connecting on "
|
||||
+ lcID + " to " + peer.calculateHash().toBase64().substring(0,6)
|
||||
+ " for socket " + s, e);
|
||||
throw new ConnectException("Unhandled error connecting: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -624,9 +658,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
|
||||
public void removeSocket(I2PSocketImpl sock) {
|
||||
String localId = sock.getLocalID();
|
||||
boolean removed = false;
|
||||
synchronized (lock) {
|
||||
_inSockets.remove(sock.getLocalID());
|
||||
_outSockets.remove(sock.getLocalID());
|
||||
removed = (null != _inSockets.remove(localId));
|
||||
removed = removed || (null != _outSockets.remove(localId));
|
||||
lock.notify();
|
||||
}
|
||||
|
||||
@ -637,9 +673,10 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
long recv = sock.getBytesReceived();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug(getName() + ": Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock
|
||||
_log.debug(getName() + ": Removing socket \"" + getReadableForm(localId) + "\" [" + sock
|
||||
+ ", send: " + sent + ", recv: " + recv
|
||||
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose + ")]",
|
||||
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose
|
||||
+ " removed? " + removed + ")]",
|
||||
new Exception("removeSocket called"));
|
||||
}
|
||||
|
||||
|
39
apps/myi2p/java/build.xml
Normal file
39
apps/myi2p/java/build.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project basedir="." default="all" name="myi2p">
|
||||
<target name="all" depends="clean, build" />
|
||||
<target name="build" depends="builddep, jar" />
|
||||
<target name="builddep">
|
||||
<ant dir="../../../core/java/" target="build" />
|
||||
</target>
|
||||
<target name="compile">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true" deprecation="on" source="1.3" target="1.3"
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar" />
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<jar destfile="./build/myi2p.jar" basedir="./build/obj" includes="**/*.class" />
|
||||
</target>
|
||||
<target name="javadoc">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/javadoc" />
|
||||
<javadoc
|
||||
sourcepath="./src:../../../core/java/src" destdir="./build/javadoc"
|
||||
packagenames="*"
|
||||
use="true"
|
||||
splitindex="true"
|
||||
windowtitle="MyI2P" />
|
||||
</target>
|
||||
<target name="clean">
|
||||
<delete dir="./build" />
|
||||
</target>
|
||||
<target name="cleandep" depends="clean">
|
||||
<ant dir="../../../core/java/" target="distclean" />
|
||||
</target>
|
||||
<target name="distclean" depends="clean">
|
||||
<ant dir="../../../core/java/" target="distclean" />
|
||||
</target>
|
||||
</project>
|
116
apps/myi2p/java/src/net/i2p/myi2p/MyI2PMessage.java
Normal file
116
apps/myi2p/java/src/net/i2p/myi2p/MyI2PMessage.java
Normal file
@ -0,0 +1,116 @@
|
||||
package net.i2p.myi2p;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
|
||||
/**
|
||||
* Packages up a message for delivery. The raw format of the message within a
|
||||
* repliable datagram is
|
||||
* <code>MyI2P $maj.$min $service $type\n$payload</code>
|
||||
* where <code>$maj.$min</code> is currently 1.0, $service is the type of MyI2P
|
||||
* service, $type is the type of message within that service, and $payload is
|
||||
* the data specific to that type.
|
||||
*
|
||||
*/
|
||||
public class MyI2PMessage {
|
||||
private Destination _peer;
|
||||
private String _service;
|
||||
private String _type;
|
||||
private byte[] _payload;
|
||||
|
||||
private static final byte[] MESSAGE_PREFIX = "MyI2P 1.0 ".getBytes();
|
||||
|
||||
/**
|
||||
* Build a new MyI2P message to be sent.
|
||||
*
|
||||
* @param to address to send the message
|
||||
* @param service what MyI2P service is involved
|
||||
* @param type type of message within that service is involved
|
||||
* @param data payload of the message to deliver
|
||||
*/
|
||||
public MyI2PMessage(Destination to, String service, String type, byte data[]) {
|
||||
_peer = to;
|
||||
_service = service;
|
||||
_type = type;
|
||||
_payload = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in the MyI2P data from the given datagram info.
|
||||
*
|
||||
* @param from authenticated from address
|
||||
* @param dgramPayload raw MyI2P formatted message
|
||||
* @throws IllegalArgumentException if the message is not a valid MyI2P message
|
||||
*/
|
||||
public MyI2PMessage(Destination from, byte dgramPayload[]) throws IllegalArgumentException {
|
||||
_peer = from;
|
||||
int index = 0;
|
||||
while (index < dgramPayload.length) {
|
||||
if (index >= MESSAGE_PREFIX.length) break;
|
||||
if (dgramPayload[index] != MESSAGE_PREFIX[index])
|
||||
throw new IllegalArgumentException("Invalid payload (not a MyI2P message)");
|
||||
index++;
|
||||
}
|
||||
|
||||
// $service $type\n$payload
|
||||
StringBuffer service = new StringBuffer(8);
|
||||
while (index < dgramPayload.length) {
|
||||
if (dgramPayload[index] == ' ') {
|
||||
_service = service.toString();
|
||||
index++;
|
||||
break;
|
||||
} else if (dgramPayload[index] == '\n') {
|
||||
throw new IllegalArgumentException("Ran into newline while reading the service");
|
||||
} else {
|
||||
service.append((char)dgramPayload[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer type = new StringBuffer(8);
|
||||
while (index < dgramPayload.length) {
|
||||
if (dgramPayload[index] == '\n') {
|
||||
_type = type.toString();
|
||||
index++;
|
||||
break;
|
||||
} else {
|
||||
service.append((char)dgramPayload[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
_payload = new byte[dgramPayload.length-index];
|
||||
System.arraycopy(dgramPayload, index, _payload, 0, _payload.length);
|
||||
}
|
||||
|
||||
/** who is this message from or who is it going to? */
|
||||
public Destination getPeer() { return _peer; }
|
||||
/** what MyI2P service is this bound for (addressBook, blog, etc)? */
|
||||
public String getServiceType() { return _service; }
|
||||
/** within that service, what type of message is this? */
|
||||
public String getMessageType() { return _type; }
|
||||
/** what is the raw data for the particular message? */
|
||||
public byte[] getPayload() { return _payload; }
|
||||
|
||||
/**
|
||||
* Retrieve the raw payload, suitable for wrapping in an I2PDatagramMaker
|
||||
* and sending to another MyI2P node.
|
||||
*
|
||||
* @throws IllegalStateException if some data is missing
|
||||
*/
|
||||
public byte[] toRawPayload() throws IllegalStateException {
|
||||
if (_service == null) throw new IllegalStateException("Service is null");
|
||||
if (_type == null) throw new IllegalStateException("Type is null");
|
||||
if (_payload == null) throw new IllegalStateException("Payload is null");
|
||||
|
||||
byte service[] = _service.getBytes();
|
||||
byte type[] = _type.getBytes();
|
||||
byte rv[] = new byte[MESSAGE_PREFIX.length + service.length + 1 + type.length + 1 + _payload.length];
|
||||
System.arraycopy(MESSAGE_PREFIX, 0, rv, 0, MESSAGE_PREFIX.length);
|
||||
System.arraycopy(service, 0, rv, MESSAGE_PREFIX.length, service.length);
|
||||
rv[MESSAGE_PREFIX.length + service.length] = ' ';
|
||||
System.arraycopy(type, 0, rv, MESSAGE_PREFIX.length + service.length + 1, type.length);
|
||||
rv[MESSAGE_PREFIX.length + service.length + 1 + type.length] = '\n';
|
||||
System.arraycopy(_payload, 0, rv, MESSAGE_PREFIX.length + service.length + 1 + type.length + 1, _payload.length);
|
||||
return rv;
|
||||
}
|
||||
}
|
266
apps/myi2p/java/src/net/i2p/myi2p/Node.java
Normal file
266
apps/myi2p/java/src/net/i2p/myi2p/Node.java
Normal file
@ -0,0 +1,266 @@
|
||||
package net.i2p.myi2p;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Main controller for a MyI2P node, coordinating all network communication and
|
||||
* distributing messages to the appropriate services.
|
||||
*
|
||||
*/
|
||||
public class Node {
|
||||
private static List _nodes = new ArrayList(1);
|
||||
/**
|
||||
* Return a list of Node instances that are currently
|
||||
* operating in the JVM
|
||||
*/
|
||||
private static List nodes() {
|
||||
synchronized (_nodes) {
|
||||
return new ArrayList(_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private NodeAdapter _adapter;
|
||||
/**
|
||||
* contains configuration properties, such where our router is, what
|
||||
* services to run, etc
|
||||
*
|
||||
*/
|
||||
private Properties _config;
|
||||
/** filename where _config is stored */
|
||||
private String _configFile = DEFAULT_CONFIG_FILE;
|
||||
/** mapping of service name (String) to Service for all services loaded */
|
||||
private Map _services;
|
||||
|
||||
private static final String DEFAULT_CONFIG_FILE = "myi2p.config";
|
||||
private static final String DEFAULT_KEY_FILE = "myi2p.keys";
|
||||
private static final String PROP_KEY_FILE = "keyFile";
|
||||
|
||||
public Node(I2PAppContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(Node.class);
|
||||
_config = new Properties();
|
||||
_services = new HashMap(1);
|
||||
if (_log.shouldLog(Log.CRIT))
|
||||
_log.log(Log.CRIT, "Node created");
|
||||
_adapter = new NodeAdapter(_context, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main driver for the node. Usage: <code>Node [configFile]</code>
|
||||
*
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
String filename = DEFAULT_CONFIG_FILE;
|
||||
if ( (args != null) && (args.length == 1) )
|
||||
filename = args[0];
|
||||
Node node = new Node(I2PAppContext.getGlobalContext());
|
||||
node.setConfigFile(filename);
|
||||
node.loadConfig();
|
||||
node.startup();
|
||||
while (true) {
|
||||
//try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
|
||||
//node.shutdown();
|
||||
//if (true) return;
|
||||
synchronized (node) {
|
||||
try { node.wait(); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Properties getConfig() {
|
||||
synchronized (_config) {
|
||||
return new Properties(_config);
|
||||
}
|
||||
}
|
||||
public void setConfig(Properties props) {
|
||||
synchronized (_config) {
|
||||
_config.clear();
|
||||
_config.putAll(props);
|
||||
}
|
||||
}
|
||||
|
||||
public String getConfigFile() { return _configFile; }
|
||||
public void setConfigFile(String filename) { _configFile = filename; }
|
||||
|
||||
/**
|
||||
* Load up the config and all of the services
|
||||
*
|
||||
*/
|
||||
public void loadConfig() {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
File cfgFile = new File(_configFile);
|
||||
if (cfgFile.exists()) {
|
||||
fis = new FileInputStream(cfgFile);
|
||||
Properties props = new Properties();
|
||||
props.load(fis);
|
||||
setConfig(props);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Config loaded from " + _configFile);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Config file " + _configFile + " does not exist, so we aren't going to do much");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error reading config file " + _configFile, ioe);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot up the node, connect to the router, and start all the services
|
||||
*
|
||||
*/
|
||||
public void startup() {
|
||||
boolean connected = connect();
|
||||
if (connected) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||
public void run() { shutdown(); }
|
||||
}));
|
||||
loadServices();
|
||||
startServices();
|
||||
synchronized (_nodes) {
|
||||
_nodes.add(this);
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Node started");
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Unable to connect, startup didn't do much");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop any connections to the network and stop all services
|
||||
*
|
||||
*/
|
||||
public void shutdown() {
|
||||
disconnect();
|
||||
stopServices();
|
||||
synchronized (_nodes) {
|
||||
_nodes.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message from the node to the peer as specified in the message
|
||||
*
|
||||
* @return true if it was sent
|
||||
*/
|
||||
public boolean sendMessage(MyI2PMessage msg) {
|
||||
return _adapter.sendMessage(msg);
|
||||
}
|
||||
|
||||
private void loadServices() {
|
||||
Properties config = getConfig();
|
||||
int i = 0;
|
||||
while (true) {
|
||||
String classname = config.getProperty("service."+i+".classname");
|
||||
if ( (classname == null) || (classname.trim().length() <= 0) )
|
||||
break;
|
||||
boolean ok = loadService("service." + i + ".", config);
|
||||
if (ok) i++;
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(i + " services loaded");
|
||||
}
|
||||
|
||||
private boolean loadService(String prefix, Properties config) {
|
||||
String classname = config.getProperty(prefix + "classname");
|
||||
String type = config.getProperty(prefix + "type");
|
||||
if (type == null) return false;
|
||||
|
||||
Properties opts = new Properties();
|
||||
int i = 0;
|
||||
while (true) {
|
||||
String name = config.getProperty(prefix + "option." + i + ".name");
|
||||
String value = config.getProperty(prefix + "option." + i + ".value");
|
||||
if ( (name == null) || (name.trim().length() <= 0) || (value == null) || (value.trim().length() <= 0) )
|
||||
break;
|
||||
opts.setProperty(name.trim(), value.trim());
|
||||
i++;
|
||||
}
|
||||
|
||||
try {
|
||||
Class cls = Class.forName(classname);
|
||||
Object obj = cls.newInstance();
|
||||
if (obj instanceof Service) {
|
||||
Service service = (Service)obj;
|
||||
service.setType(type);
|
||||
service.setOptions(opts);
|
||||
service.setNode(this);
|
||||
service.setContext(_context);
|
||||
synchronized (_services) {
|
||||
_services.put(type, service);
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Service " + type + " loaded");
|
||||
return true;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error loading service " + type + ": not a service [" + classname + "]");
|
||||
}
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error loading service " + type + ": class " + classname + " is invalid", cnfe);
|
||||
} catch (InstantiationException ie) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error instantiating service " + type + ": class " + classname + " could not be created", ie);
|
||||
} catch (IllegalAccessException iae) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error creating service " + type + ": class " + classname + " could not be accessed", iae);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean connect() {
|
||||
Properties config = getConfig();
|
||||
File keyFile = new File(config.getProperty(PROP_KEY_FILE, DEFAULT_KEY_FILE));
|
||||
return _adapter.connect(config, keyFile);
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
_adapter.disconnect();
|
||||
}
|
||||
|
||||
private void startServices() {
|
||||
for (Iterator iter = _services.values().iterator(); iter.hasNext(); ) {
|
||||
Service service = (Service)iter.next();
|
||||
service.startup();
|
||||
}
|
||||
}
|
||||
private void stopServices() {
|
||||
for (Iterator iter = _services.values().iterator(); iter.hasNext(); ) {
|
||||
Service service = (Service)iter.next();
|
||||
service.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessage(MyI2PMessage msg) {
|
||||
Service service = (Service)_services.get(msg.getServiceType());
|
||||
if (service == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Message received for an unknown service ["
|
||||
+ msg.getServiceType() + "] from "
|
||||
+ msg.getPeer().calculateHash().toBase64());
|
||||
} else {
|
||||
service.receiveMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
178
apps/myi2p/java/src/net/i2p/myi2p/NodeAdapter.java
Normal file
178
apps/myi2p/java/src/net/i2p/myi2p/NodeAdapter.java
Normal file
@ -0,0 +1,178 @@
|
||||
package net.i2p.myi2p;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionListener;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.datagram.I2PDatagramDissector;
|
||||
import net.i2p.client.datagram.I2PDatagramMaker;
|
||||
import net.i2p.client.datagram.I2PInvalidDatagramException;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Bind the MyI2P node to the I2P network, handling messages, sessions,
|
||||
* etc.
|
||||
*
|
||||
*/
|
||||
public class NodeAdapter implements I2PSessionListener {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private Node _node;
|
||||
private I2PSession _session;
|
||||
|
||||
public NodeAdapter(I2PAppContext context, Node node) {
|
||||
_node = node;
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(NodeAdapter.class);
|
||||
}
|
||||
|
||||
boolean sendMessage(MyI2PMessage msg) {
|
||||
if (_session == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Cannot send the message, as we are not connected");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
I2PDatagramMaker builder = new I2PDatagramMaker(_session);
|
||||
byte dgram[] = builder.makeI2PDatagram(msg.toRawPayload());
|
||||
return _session.sendMessage(msg.getPeer(), dgram);
|
||||
} catch (IllegalStateException ise) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("MyI2PMessage was not valid", ise);
|
||||
return false;
|
||||
} catch (I2PSessionException ise) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error sending to the peer", ise);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the network using the current I2CP config and the private
|
||||
* key file specified in the node config. If the file does not exist, a new
|
||||
* destination will be created.
|
||||
*
|
||||
* @param config MyI2P node and I2CP configuration
|
||||
* @param keyFile file to load the private keystream from (if it doesn't
|
||||
* exist, a new one will be created and stored at that location)
|
||||
*
|
||||
* @return true if connection was successful, false otherwise
|
||||
*/
|
||||
boolean connect(Properties config, File keyFile) {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
if (!keyFile.exists()) {
|
||||
File parent = keyFile.getParentFile();
|
||||
if (parent != null) parent.mkdirs();
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(keyFile);
|
||||
Destination dest = client.createDestination(fos);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("New destination created ["
|
||||
+ dest.calculateHash().toBase64()
|
||||
+ "] with keys at " + keyFile);
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error writing new keystream to " + keyFile, ioe);
|
||||
return false;
|
||||
} catch (I2PException ie) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Internal error creating new destination", ie);
|
||||
return false;
|
||||
} finally {
|
||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(keyFile);
|
||||
_session = client.createSession(fis, config);
|
||||
if (_session == null) {
|
||||
_log.error("wtf, why did it create a null session?");
|
||||
return false;
|
||||
}
|
||||
_session.setSessionListener(this);
|
||||
_session.connect();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("I2P session created");
|
||||
return true;
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Unable to read the keystream from " + keyFile, ioe);
|
||||
return false;
|
||||
} catch (I2PSessionException ise) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Unable to connect to the router", ise);
|
||||
return false;
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
if (_session != null) {
|
||||
try {
|
||||
_session.destroySession();
|
||||
} catch (I2PSessionException ise) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error destroying the session in shutdown", ise);
|
||||
}
|
||||
_session = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnected(I2PSession session) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Session disconnected");
|
||||
}
|
||||
|
||||
public void errorOccurred(I2PSession session, String message, Throwable error) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Session error occurred - " + message, error);
|
||||
}
|
||||
|
||||
public void messageAvailable(I2PSession session, int msgId, long size) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("message available [" + msgId + "/"+ size + " bytes]");
|
||||
|
||||
try {
|
||||
byte data[] = session.receiveMessage(msgId);
|
||||
I2PDatagramDissector dissector = new I2PDatagramDissector();
|
||||
dissector.loadI2PDatagram(data);
|
||||
try {
|
||||
MyI2PMessage msg = new MyI2PMessage(dissector.getSender(), dissector.getPayload());
|
||||
_node.handleMessage(msg);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Message is a valid datagram but invalid MyI2P message", iae);
|
||||
}
|
||||
} catch (I2PSessionException ise) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error retrieving message payload for message " + msgId, ise);
|
||||
} catch (I2PInvalidDatagramException iide) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Message received was not a valid repliable datagram", iide);
|
||||
} catch (DataFormatException dfe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Message received was a corrupt repliable datagram", dfe);
|
||||
}
|
||||
}
|
||||
|
||||
public void reportAbuse(I2PSession session, int severity) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("abuse occurred");
|
||||
}
|
||||
}
|
35
apps/myi2p/java/src/net/i2p/myi2p/Service.java
Normal file
35
apps/myi2p/java/src/net/i2p/myi2p/Service.java
Normal file
@ -0,0 +1,35 @@
|
||||
package net.i2p.myi2p;
|
||||
|
||||
import java.util.Properties;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
/**
|
||||
* Defines a service that can operate within a MyI2P node, responding to
|
||||
* messages and performing whatever tasks are necessary.
|
||||
*
|
||||
*/
|
||||
public interface Service {
|
||||
/** what type of message will this service respond to? */
|
||||
public String getType();
|
||||
public void setType(String type);
|
||||
|
||||
/** what node is this service hooked into */
|
||||
public Node getNode();
|
||||
public void setNode(Node node);
|
||||
|
||||
/** what options specific to this node does the service have? */
|
||||
public Properties getOptions();
|
||||
public void setOptions(Properties opts);
|
||||
|
||||
/** give the service a scope */
|
||||
public I2PAppContext getContext();
|
||||
public void setContext(I2PAppContext context);
|
||||
|
||||
/** called when a message is received for the service */
|
||||
public void receiveMessage(MyI2PMessage msg);
|
||||
|
||||
/** start the service up - the node is ready */
|
||||
public void startup();
|
||||
/** shut the service down - the node is going offline */
|
||||
public void shutdown();
|
||||
}
|
36
apps/myi2p/java/src/net/i2p/myi2p/ServiceImpl.java
Normal file
36
apps/myi2p/java/src/net/i2p/myi2p/ServiceImpl.java
Normal file
@ -0,0 +1,36 @@
|
||||
package net.i2p.myi2p;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.myi2p.Service;
|
||||
import net.i2p.myi2p.Node;
|
||||
import net.i2p.myi2p.MyI2PMessage;
|
||||
|
||||
/**
|
||||
* Base service implementation
|
||||
*
|
||||
*/
|
||||
public abstract class ServiceImpl implements Service {
|
||||
private I2PAppContext _context;
|
||||
private Node _node;
|
||||
private Properties _options;
|
||||
private String _serviceType;
|
||||
|
||||
public ServiceImpl() {
|
||||
_context = null;
|
||||
_node = null;
|
||||
_options = null;
|
||||
_serviceType = null;
|
||||
}
|
||||
|
||||
// base inspectors / mutators
|
||||
public Node getNode() { return _node; }
|
||||
public void setNode(Node node) { _node = node; }
|
||||
public I2PAppContext getContext() { return _context; }
|
||||
public void setContext(I2PAppContext context) { _context = context; }
|
||||
public Properties getOptions() { return _options; }
|
||||
public void setOptions(Properties opts) { _options = opts; }
|
||||
public String getType() { return _serviceType; }
|
||||
public void setType(String type) { _serviceType = type; }
|
||||
}
|
126
apps/myi2p/java/src/net/i2p/myi2p/address/AddressBook.java
Normal file
126
apps/myi2p/java/src/net/i2p/myi2p/address/AddressBook.java
Normal file
@ -0,0 +1,126 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
|
||||
/**
|
||||
* Main lookup component for maintaining references to other I2P destinations.
|
||||
*
|
||||
*/
|
||||
public class AddressBook {
|
||||
private I2PAppContext _context;
|
||||
/** Name (String) to AddressBookEntry */
|
||||
private Map _entries;
|
||||
/**
|
||||
* List of NameReference that has been received but whose preferred
|
||||
* name conflicts with an existing entry.
|
||||
*/
|
||||
private List _conflictingReferences;
|
||||
|
||||
public AddressBook(I2PAppContext context) {
|
||||
_context = context;
|
||||
_entries = new HashMap(16);
|
||||
_conflictingReferences = new ArrayList(0);
|
||||
}
|
||||
|
||||
/** retrieve a list of entry names (strings) */
|
||||
public Set getEntryNames() {
|
||||
synchronized (_entries) {
|
||||
return new HashSet(_entries.keySet());
|
||||
}
|
||||
}
|
||||
public AddressBookEntry getEntry(String name) {
|
||||
synchronized (_entries) {
|
||||
return (AddressBookEntry)_entries.get(name);
|
||||
}
|
||||
}
|
||||
public AddressBookEntry addEntry(AddressBookEntry entry) {
|
||||
synchronized (_entries) {
|
||||
return (AddressBookEntry)_entries.put(entry.getLocalName(), entry);
|
||||
}
|
||||
}
|
||||
public void removeEntry(String name) {
|
||||
synchronized (_entries) {
|
||||
_entries.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public int getConflictingReferenceCount() {
|
||||
synchronized (_conflictingReferences) {
|
||||
return _conflictingReferences.size();
|
||||
}
|
||||
}
|
||||
public NameReference getConflictingReference(int index) {
|
||||
synchronized (_conflictingReferences) {
|
||||
return (NameReference)_conflictingReferences.get(index);
|
||||
}
|
||||
}
|
||||
public void addConflictingReference(NameReference ref) {
|
||||
synchronized (_conflictingReferences) {
|
||||
_conflictingReferences.add(ref);
|
||||
}
|
||||
}
|
||||
public void removeConflictingReference(int index) {
|
||||
synchronized (_conflictingReferences) {
|
||||
_conflictingReferences.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void read(InputStream in) throws IOException {
|
||||
try {
|
||||
int numEntries = (int)DataHelper.readLong(in, 2);
|
||||
if (numEntries < 0) throw new IOException("Corrupt AddressBook - " + numEntries + " entries?");
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
AddressBookEntry entry = new AddressBookEntry(_context);
|
||||
entry.read(in);
|
||||
addEntry(entry);
|
||||
}
|
||||
int numConflicting = (int)DataHelper.readLong(in, 2);
|
||||
if (numConflicting < 0) throw new IOException("Corrupt AddressBook - " + numConflicting + " conflicting?");
|
||||
for (int i = 0; i < numConflicting; i++) {
|
||||
NameReference ref = new NameReference(_context);
|
||||
ref.read(in);
|
||||
addConflictingReference(ref);
|
||||
}
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt address book - " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
public void write(OutputStream out) throws IOException {
|
||||
try {
|
||||
synchronized (_entries) {
|
||||
DataHelper.writeLong(out, 2, _entries.size());
|
||||
for (Iterator iter = _entries.values().iterator(); iter.hasNext(); ) {
|
||||
AddressBookEntry entry = (AddressBookEntry)iter.next();
|
||||
entry.write(out);
|
||||
}
|
||||
}
|
||||
synchronized (_conflictingReferences) {
|
||||
DataHelper.writeLong(out, 2, _conflictingReferences.size());
|
||||
for (int i = 0; i < _conflictingReferences.size(); i++) {
|
||||
NameReference ref = (NameReference)_conflictingReferences.get(i);
|
||||
ref.write(out);
|
||||
}
|
||||
}
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt address book - " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Entries: " + _entries.size() + " conflicting: " + _conflictingReferences.size();
|
||||
}
|
||||
}
|
142
apps/myi2p/java/src/net/i2p/myi2p/address/AddressBookEntry.java
Normal file
142
apps/myi2p/java/src/net/i2p/myi2p/address/AddressBookEntry.java
Normal file
@ -0,0 +1,142 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
|
||||
/**
|
||||
* Implements a local address book entry, pointing at a known secure
|
||||
* NameReference as well as an optional Subscription.
|
||||
*
|
||||
*/
|
||||
public class AddressBookEntry {
|
||||
private I2PAppContext _context;
|
||||
private String _localName;
|
||||
private Properties _options;
|
||||
private NameReference _reference;
|
||||
private Subscription _subscription;
|
||||
private long _addedOn;
|
||||
|
||||
public AddressBookEntry(I2PAppContext context) {
|
||||
_context = context;
|
||||
_localName = null;
|
||||
_options = new Properties();
|
||||
_reference = null;
|
||||
_subscription = null;
|
||||
_addedOn = context.clock().now();
|
||||
}
|
||||
|
||||
/** Local (unique) name we use to reference the given destination */
|
||||
public String getLocalName() { return _localName; }
|
||||
public void setLocalName(String name) { _localName = name; }
|
||||
|
||||
public Properties getOptions() {
|
||||
synchronized (_options) {
|
||||
return new Properties(_options);
|
||||
}
|
||||
}
|
||||
public void setOptions(Properties props) {
|
||||
synchronized (_options) {
|
||||
_options.clear();
|
||||
if (props != null)
|
||||
_options.putAll(props);
|
||||
}
|
||||
}
|
||||
|
||||
/** Secure name reference, provided by the destination */
|
||||
public NameReference getNameReference() { return _reference; }
|
||||
public void setNameReference(NameReference ref) { _reference = ref; }
|
||||
|
||||
/**
|
||||
* If specified, the details of our subscription to the MyI2P address
|
||||
* book at the referenced destination.
|
||||
*
|
||||
*/
|
||||
public Subscription getSubscription() { return _subscription; }
|
||||
public void setSubscription(Subscription sub) { _subscription = sub; }
|
||||
|
||||
/** When this entry was added */
|
||||
public long getAddedOn() { return _addedOn; }
|
||||
public void setAddedOn(long when) { _addedOn = when; }
|
||||
|
||||
/** load the data from the stream */
|
||||
public void read(InputStream in) throws IOException {
|
||||
try {
|
||||
Boolean localNameDefined = DataHelper.readBoolean(in);
|
||||
if ( (localNameDefined != null) && (localNameDefined.booleanValue()) )
|
||||
_localName = DataHelper.readString(in);
|
||||
else
|
||||
_localName = null;
|
||||
|
||||
Date when = DataHelper.readDate(in);
|
||||
if (when == null)
|
||||
_addedOn = -1;
|
||||
else
|
||||
_addedOn = when.getTime();
|
||||
|
||||
Properties props = DataHelper.readProperties(in);
|
||||
setOptions(props);
|
||||
|
||||
Boolean refDefined = DataHelper.readBoolean(in);
|
||||
if ( (refDefined != null) && (refDefined.booleanValue()) ) {
|
||||
_reference = new NameReference(_context);
|
||||
_reference.read(in);
|
||||
} else {
|
||||
_reference = null;
|
||||
}
|
||||
|
||||
Boolean subDefined = DataHelper.readBoolean(in);
|
||||
if ( (subDefined != null) && (subDefined.booleanValue()) ) {
|
||||
Subscription sub = new Subscription(_context);
|
||||
sub.read(in);
|
||||
_subscription = sub;
|
||||
} else {
|
||||
_subscription = null;
|
||||
}
|
||||
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt subscription: " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** persist the data to the stream */
|
||||
public void write(OutputStream out) throws IOException {
|
||||
try {
|
||||
if ( (_localName != null) && (_localName.trim().length() > 0) ) {
|
||||
DataHelper.writeBoolean(out, Boolean.TRUE);
|
||||
DataHelper.writeString(out, _localName);
|
||||
} else {
|
||||
DataHelper.writeBoolean(out, Boolean.FALSE);
|
||||
}
|
||||
|
||||
DataHelper.writeDate(out, new Date(_addedOn));
|
||||
|
||||
synchronized (_options) {
|
||||
DataHelper.writeProperties(out, _options);
|
||||
}
|
||||
|
||||
if (_reference != null) {
|
||||
DataHelper.writeBoolean(out, Boolean.TRUE);
|
||||
_reference.write(out);
|
||||
} else {
|
||||
DataHelper.writeBoolean(out, Boolean.FALSE);
|
||||
}
|
||||
|
||||
if (_subscription != null) {
|
||||
DataHelper.writeBoolean(out, Boolean.TRUE);
|
||||
_subscription.write(out);
|
||||
} else {
|
||||
DataHelper.writeBoolean(out, Boolean.FALSE);
|
||||
}
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt subscription: " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import net.i2p.myi2p.Service;
|
||||
import net.i2p.myi2p.ServiceImpl;
|
||||
import net.i2p.myi2p.Node;
|
||||
import net.i2p.myi2p.MyI2PMessage;
|
||||
|
||||
/**
|
||||
* Main service handler / coordinator for the MyI2P address book.
|
||||
*
|
||||
*/
|
||||
public class AddressBookService extends ServiceImpl {
|
||||
private Log _log;
|
||||
private AddressBook _addressBook;
|
||||
/** contains a mapping of event time (Long) to description (String) */
|
||||
private Map _activityLog;
|
||||
private String _addressBookFile;
|
||||
|
||||
private static String PROP_ADDRESSBOOK_FILE = "datafile";
|
||||
private static String DEFAULT_ADDRESSBOOK_FILE = "addressbook.dat";
|
||||
|
||||
public static final String SERVICE_TYPE = "AddressBook";
|
||||
public String getType() { return SERVICE_TYPE; }
|
||||
|
||||
public void startup() {
|
||||
_log = getContext().logManager().getLog(AddressBookService.class);
|
||||
|
||||
_addressBookFile = getOptions().getProperty(PROP_ADDRESSBOOK_FILE, DEFAULT_ADDRESSBOOK_FILE);
|
||||
File file = new File(_addressBookFile);
|
||||
|
||||
if (file.exists()) {
|
||||
loadData(file);
|
||||
} else {
|
||||
_addressBook = new AddressBook(getContext());
|
||||
_activityLog = new HashMap(16);
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
File file = new File(_addressBookFile);
|
||||
storeData(file);
|
||||
}
|
||||
|
||||
public void receiveMessage(MyI2PMessage msg) {
|
||||
_log.info("Received a " + msg.getMessageType() + " from "
|
||||
+ msg.getPeer().calculateHash().toBase64()
|
||||
+ new String(msg.getPayload()));
|
||||
}
|
||||
|
||||
/** load everything from disk */
|
||||
private void loadData(File dataFile) {
|
||||
AddressBookServiceData data = new AddressBookServiceData(getContext());
|
||||
data.load(dataFile);
|
||||
if (data.getErrorMessage() != null) {
|
||||
_log.warn(data.getErrorMessage(), data.getError());
|
||||
_addressBook = new AddressBook(getContext());
|
||||
_activityLog = new HashMap(16);
|
||||
} else {
|
||||
_addressBook = data.getAddressBook();
|
||||
_activityLog = data.getActivityLog();
|
||||
}
|
||||
}
|
||||
|
||||
/** persist everything to disk */
|
||||
private void storeData(File dataFile) {
|
||||
AddressBookServiceData data = new AddressBookServiceData(getContext());
|
||||
data.setActivityLog(_activityLog);
|
||||
data.setAddressBook(_addressBook);
|
||||
data.store(dataFile);
|
||||
if (data.getErrorMessage() != null) {
|
||||
_log.warn(data.getErrorMessage(), data.getError());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Component for loading and storing the service data to disk
|
||||
*
|
||||
*/
|
||||
public class AddressBookServiceData {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private AddressBook _addressBook;
|
||||
private Map _activityLog;
|
||||
private Exception _error;
|
||||
private String _errorMessage;
|
||||
|
||||
public AddressBookServiceData(I2PAppContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(AddressBookServiceData.class);
|
||||
_addressBook = null;
|
||||
_activityLog = null;
|
||||
_error = null;
|
||||
_errorMessage = null;
|
||||
}
|
||||
|
||||
public AddressBook getAddressBook() { return _addressBook; }
|
||||
public void setAddressBook(AddressBook book) { _addressBook = book; }
|
||||
public Map getActivityLog() { return _activityLog; }
|
||||
public void setActivityLog(Map log) { _activityLog = log; }
|
||||
|
||||
public Exception getError() { return _error; }
|
||||
public String getErrorMessage() { return _errorMessage; }
|
||||
|
||||
public void load(File from) {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(from);
|
||||
AddressBook addressBook = new AddressBook(_context);
|
||||
addressBook.read(fis);
|
||||
_addressBook = addressBook;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Address book: " + addressBook);
|
||||
Properties props = DataHelper.readProperties(fis);
|
||||
Map log = new HashMap(props.size());
|
||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
String event = props.getProperty(key);
|
||||
long when = 0;
|
||||
try {
|
||||
when = Long.parseLong(key);
|
||||
while (log.containsKey(new Long(when)))
|
||||
when++;
|
||||
log.put(new Long(when), event);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Activity log: on " + new Date(when) + ": " + event);
|
||||
} catch (NumberFormatException nfe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Corrupt activity log entry: when=" + key, nfe);
|
||||
}
|
||||
}
|
||||
_activityLog = log;
|
||||
} catch (Exception e) {
|
||||
_error = e;
|
||||
_errorMessage = "Error reading the address book from " + from;
|
||||
}
|
||||
}
|
||||
|
||||
public void store(File to) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(to);
|
||||
_addressBook.write(fos);
|
||||
Properties props = new Properties();
|
||||
for (Iterator iter = _activityLog.keySet().iterator(); iter.hasNext(); ) {
|
||||
Long when = (Long)iter.next();
|
||||
String msg = (String)_activityLog.get(when);
|
||||
props.setProperty(when.toString(), msg);
|
||||
}
|
||||
DataHelper.writeProperties(fos, props);
|
||||
} catch (Exception e) {
|
||||
_error = e;
|
||||
_errorMessage = "Error writing the address book to " + to;
|
||||
} finally {
|
||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
154
apps/myi2p/java/src/net/i2p/myi2p/address/CreateEntryCLI.java
Normal file
154
apps/myi2p/java/src/net/i2p/myi2p/address/CreateEntryCLI.java
Normal file
@ -0,0 +1,154 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* CreateEntryCLI addressBookFile referenceFile localName subscriptionFrequencyHours [ key=value]*
|
||||
*/
|
||||
public class CreateEntryCLI {
|
||||
private I2PAppContext _context;
|
||||
private String _args[];
|
||||
private String _addressBook;
|
||||
private String _referenceFile;
|
||||
private String _localName;
|
||||
private int _subscriptionFrequencyHours;
|
||||
private Properties _options;
|
||||
|
||||
public CreateEntryCLI(String args[]) {
|
||||
_context = new I2PAppContext();
|
||||
_args = args;
|
||||
_options = new Properties();
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
if (parseArgs())
|
||||
doExecute();
|
||||
else
|
||||
System.err.println("Usage: CreateEntryCLI addressBookFile referenceFile localName subscriptionFrequencyHours[ key=value]*");
|
||||
}
|
||||
|
||||
private boolean parseArgs() {
|
||||
if ( (_args == null) || (_args.length < 3) )
|
||||
return false;
|
||||
_addressBook = _args[0];
|
||||
_referenceFile = _args[1];
|
||||
_localName = _args[2];
|
||||
try {
|
||||
_subscriptionFrequencyHours = Integer.parseInt(_args[3]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 4; i < _args.length; i++) {
|
||||
int eq = _args[i].indexOf('=');
|
||||
if ( (eq <= 0) || (eq >= _args[i].length() - 1) )
|
||||
continue;
|
||||
String key = _args[i].substring(0,eq);
|
||||
String val = _args[i].substring(eq+1);
|
||||
_options.setProperty(key, val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void doExecute() {
|
||||
AddressBookServiceData data = new AddressBookServiceData(_context);
|
||||
File f = new File(_addressBook);
|
||||
if (f.exists()) {
|
||||
data.load(f);
|
||||
if (data.getError() != null) {
|
||||
if (data.getErrorMessage() != null)
|
||||
System.err.println(data.getErrorMessage());
|
||||
data.getError().printStackTrace();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
data.setAddressBook(new AddressBook(_context));
|
||||
data.setActivityLog(new HashMap());
|
||||
}
|
||||
NameReference ref = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(_referenceFile);
|
||||
ref = new NameReference(_context);
|
||||
ref.read(fis);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Name reference under " + _referenceFile + " is corrupt");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
AddressBook book = data.getAddressBook();
|
||||
Map activityLog = data.getActivityLog();
|
||||
|
||||
AddressBookEntry oldEntry = book.getEntry(_localName);
|
||||
|
||||
AddressBookEntry entry = new AddressBookEntry(_context);
|
||||
entry.setLocalName(_localName);
|
||||
entry.setNameReference(ref);
|
||||
|
||||
Subscription sub = new Subscription(_context);
|
||||
sub.setQueryFrequencyMinutes(60*_subscriptionFrequencyHours);
|
||||
|
||||
entry.setSubscription(sub);
|
||||
entry.setOptions(_options);
|
||||
|
||||
if (oldEntry == null) {
|
||||
book.addEntry(entry);
|
||||
System.out.println("New address book entry added for " + entry.getLocalName());
|
||||
activityLog.put(new Long(_context.clock().now()), "New address book entry added for " + entry.getLocalName());
|
||||
} else {
|
||||
Destination oldDest = oldEntry.getNameReference().getDestination();
|
||||
if (oldDest.equals(ref.getDestination())) {
|
||||
if (ref.getSequenceNum() < oldEntry.getNameReference().getSequenceNum()) {
|
||||
System.err.println("Not updating the address book - newer reference for " + entry.getLocalName() + " exists");
|
||||
return;
|
||||
} else {
|
||||
// same or newer rev
|
||||
if (null != entry.getSubscription()) {
|
||||
if (null != oldEntry.getSubscription()) {
|
||||
entry.getSubscription().setLastQueryAttempt(oldEntry.getSubscription().getLastQueryAttempt());
|
||||
entry.getSubscription().setLastQuerySuccess(oldEntry.getSubscription().getLastQuerySuccess());
|
||||
}
|
||||
}
|
||||
book.addEntry(entry);
|
||||
System.err.println("Updating the options and subscription for an existing reference to " + entry.getLocalName());
|
||||
activityLog.put(new Long(_context.clock().now()), "Updating options and subscription for " + entry.getLocalName());
|
||||
}
|
||||
} else {
|
||||
book.addConflictingReference(ref);
|
||||
System.out.println("Old entry exists for " + _localName + " - adding a conflicting reference");
|
||||
System.out.println("Existing entry points to " + oldEntry.getNameReference().getDestination().calculateHash().toBase64());
|
||||
System.out.println("New entry points to " + entry.getNameReference().getDestination().calculateHash().toBase64());
|
||||
|
||||
activityLog.put(new Long(_context.clock().now()), "Adding conflicting reference for " + entry.getLocalName());
|
||||
}
|
||||
}
|
||||
|
||||
data.setAddressBook(book);
|
||||
data.setActivityLog(activityLog);
|
||||
|
||||
data.store(f);
|
||||
if (data.getError() != null) {
|
||||
if (data.getErrorMessage() != null)
|
||||
System.err.println(data.getErrorMessage());
|
||||
data.getError().printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
CreateEntryCLI cli = new CreateEntryCLI(args);
|
||||
cli.execute();
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* CreateNameReferenceCLI outputFile privateDestFile preferredName sequenceNum serviceType[ key=value]*
|
||||
*/
|
||||
public class CreateNameReferenceCLI {
|
||||
private I2PAppContext _context;
|
||||
private String _args[];
|
||||
private String _outputFile;
|
||||
private String _destFile;
|
||||
private String _preferredName;
|
||||
private long _sequenceNum;
|
||||
private String _serviceType;
|
||||
private Properties _options;
|
||||
|
||||
public CreateNameReferenceCLI(String[] args) {
|
||||
_context = new I2PAppContext();
|
||||
_args = args;
|
||||
_options = new Properties();
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
if (parseArgs())
|
||||
doExecute();
|
||||
else
|
||||
System.err.println("Usage: CreateNameReferenceCLI outputFile privateDestFile preferredName sequenceNum serviceType[ key=value]*");
|
||||
}
|
||||
|
||||
private boolean parseArgs() {
|
||||
if ( (_args == null) || (_args.length < 4) )
|
||||
return false;
|
||||
_outputFile = _args[0];
|
||||
_destFile = _args[1];
|
||||
_preferredName = _args[2];
|
||||
try {
|
||||
_sequenceNum = Long.parseLong(_args[3]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return false;
|
||||
}
|
||||
_serviceType = _args[4];
|
||||
|
||||
for (int i = 5; i < _args.length; i++) {
|
||||
int eq = _args[i].indexOf('=');
|
||||
if ( (eq <= 0) || (eq >= _args[i].length() - 1) )
|
||||
continue;
|
||||
String key = _args[i].substring(0,eq);
|
||||
String val = _args[i].substring(eq+1);
|
||||
_options.setProperty(key, val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void doExecute() {
|
||||
Destination dest = null;
|
||||
SigningPrivateKey priv = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(_destFile);
|
||||
dest = new Destination();
|
||||
dest.readBytes(fis);
|
||||
PrivateKey whocares = new PrivateKey();
|
||||
whocares.readBytes(fis);
|
||||
priv = new SigningPrivateKey();
|
||||
priv.readBytes(fis);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Destination private keys under " + _destFile + " are corrupt");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
NameReference ref = new NameReference(_context);
|
||||
ref.setDestination(dest);
|
||||
ref.setPreferredName(_preferredName);
|
||||
ref.setSequenceNum(_sequenceNum);
|
||||
ref.setServiceType(_serviceType);
|
||||
if (_options != null) {
|
||||
for (Iterator iter = _options.keySet().iterator(); iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
String val = _options.getProperty(key);
|
||||
ref.setOption(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ref.sign(priv);
|
||||
} catch (IllegalStateException ise) {
|
||||
System.err.println("Error signing the new reference");
|
||||
ise.printStackTrace();
|
||||
}
|
||||
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(_outputFile);
|
||||
ref.write(fos);
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("Error writing out the new reference");
|
||||
ioe.printStackTrace();
|
||||
} finally {
|
||||
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
System.out.println("Reference created at " + _outputFile);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
CreateNameReferenceCLI cli = new CreateNameReferenceCLI(args);
|
||||
cli.execute();
|
||||
}
|
||||
}
|
198
apps/myi2p/java/src/net/i2p/myi2p/address/NameReference.java
Normal file
198
apps/myi2p/java/src/net/i2p/myi2p/address/NameReference.java
Normal file
@ -0,0 +1,198 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Define a verified and immutable reference to a particular I2P destination.
|
||||
*
|
||||
*/
|
||||
public class NameReference {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private Destination _destination;
|
||||
private String _preferredName;
|
||||
private String _serviceType;
|
||||
private long _sequenceNum;
|
||||
private Properties _options;
|
||||
private Signature _signature;
|
||||
|
||||
public static final byte[] VERSION_PREFIX = "MyI2P_NameReference_1.0".getBytes();
|
||||
|
||||
public NameReference(I2PAppContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(NameReference.class);
|
||||
_destination = null;
|
||||
_preferredName = null;
|
||||
_serviceType = null;
|
||||
_sequenceNum = -1;
|
||||
_options = new Properties();
|
||||
_signature = null;
|
||||
}
|
||||
|
||||
/** retrieve the destination this reference points at */
|
||||
public Destination getDestination() { return _destination; }
|
||||
public void setDestination(Destination dest) { _destination = dest; }
|
||||
|
||||
/** retrieve the name this destination would like to be called */
|
||||
public String getPreferredName() { return _preferredName; }
|
||||
public void setPreferredName(String name) { _preferredName = name; }
|
||||
|
||||
/** retrieve the type of service at this destination (eepsite, ircd, etc) */
|
||||
public String getServiceType() { return _serviceType; }
|
||||
public void setServiceType(String type) { _serviceType = type; }
|
||||
|
||||
/**
|
||||
* data point to allow the reference to be updated. The reference with the
|
||||
* larger sequence number should clobber an older reference.
|
||||
*
|
||||
*/
|
||||
public long getSequenceNum() { return _sequenceNum; }
|
||||
public void setSequenceNum(long num) { _sequenceNum = num; }
|
||||
|
||||
/** Get a list of option names (strings) */
|
||||
public Set getOptionNames() { return new HashSet(_options.keySet()); }
|
||||
|
||||
/** Access any options published in the reference */
|
||||
public String getOption(String name) { return (String)_options.getProperty(name); }
|
||||
|
||||
/**
|
||||
* Specify a particular value for an option. If the value is null, the
|
||||
* entry is removed. The name cannot have an '=' or newline, and the
|
||||
* value cannot have a newline.
|
||||
*
|
||||
* @throws IllegalArgumentException if the name or value is illegal
|
||||
*/
|
||||
public void setOption(String name, String value) {
|
||||
if (name == null) throw new IllegalArgumentException("Missing name");
|
||||
if (name.indexOf('=') != -1)
|
||||
throw new IllegalArgumentException("Name cannot have an = sign");
|
||||
if (name.indexOf('\n') != -1)
|
||||
throw new IllegalArgumentException("Name cannot have a newline");
|
||||
|
||||
if (value != null) {
|
||||
if (value.indexOf('\n') != -1)
|
||||
throw new IllegalArgumentException("Values do not allow newlines");
|
||||
_options.setProperty(name, value);
|
||||
} else {
|
||||
_options.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
/** Access the DSA signature authenticating this reference */
|
||||
public Signature getSignature() { return _signature; }
|
||||
public void setSignature(Signature sig) { _signature = sig; }
|
||||
|
||||
/** Verify the DSA signature, returning true if it is valid, false otherwise */
|
||||
public boolean validate() {
|
||||
try {
|
||||
byte raw[] = toSignableByteArray();
|
||||
return _context.dsa().verifySignature(_signature, raw, _destination.getSigningPublicKey());
|
||||
} catch (IllegalStateException ise) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign the data
|
||||
*
|
||||
* @throws IllegalStateException if the data is invalid
|
||||
*/
|
||||
public void sign(SigningPrivateKey key) throws IllegalStateException {
|
||||
byte signable[] = toSignableByteArray();
|
||||
_signature = _context.dsa().sign(signable, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the full serialized and signed version of this name reference
|
||||
*
|
||||
* @throws IllegalStateException if the signature or other data is invalid
|
||||
*/
|
||||
public void write(OutputStream out) throws IllegalStateException, IOException {
|
||||
if (_signature == null) throw new IllegalStateException("No signature");
|
||||
byte signable[] = toSignableByteArray();
|
||||
out.write(signable);
|
||||
try {
|
||||
_signature.writeBytes(out);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IllegalStateException("Signature was corrupt - " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the signable (but not including the signature) name reference
|
||||
*
|
||||
* @throws IllegalStateException if the data is invalid
|
||||
*/
|
||||
private byte[] toSignableByteArray() throws IllegalStateException {
|
||||
if (_sequenceNum < 0) throw new IllegalStateException("Sequence number is invalid");
|
||||
if (_preferredName == null) throw new IllegalStateException("Preferred name is invalid");
|
||||
if (_serviceType == null) throw new IllegalStateException("Service type is invalid");
|
||||
if (_options == null) throw new IllegalStateException("Options not constructed");
|
||||
if (_destination == null) throw new IllegalStateException("Destination not specified");
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||
try {
|
||||
baos.write(VERSION_PREFIX);
|
||||
_destination.writeBytes(baos);
|
||||
DataHelper.writeLong(baos, 4, _sequenceNum);
|
||||
DataHelper.writeString(baos, _preferredName);
|
||||
DataHelper.writeString(baos, _serviceType);
|
||||
DataHelper.writeProperties(baos, _options); // sorts alphabetically
|
||||
return baos.toByteArray();
|
||||
} catch (DataFormatException dfe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Corrupted trying to write entry", dfe);
|
||||
return null;
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("IOError writing to memory?", ioe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a full signed reference from the given stream
|
||||
*
|
||||
* @throws DataFormatException if the reference is corrupt
|
||||
* @throws IOException if there is an error reading the stream
|
||||
*/
|
||||
public void read(InputStream in) throws DataFormatException, IOException {
|
||||
byte versionBuf[] = new byte[VERSION_PREFIX.length];
|
||||
int len = DataHelper.read(in, versionBuf);
|
||||
if (len != versionBuf.length)
|
||||
throw new IllegalArgumentException("Version length too short ("+ len + ")");
|
||||
if (!DataHelper.eq(versionBuf, VERSION_PREFIX))
|
||||
throw new IllegalArgumentException("Version mismatch (" + new String(versionBuf) + ")");
|
||||
Destination dest = new Destination();
|
||||
dest.readBytes(in);
|
||||
long seq = DataHelper.readLong(in, 4);
|
||||
String name = DataHelper.readString(in);
|
||||
String type = DataHelper.readString(in);
|
||||
Properties opts = DataHelper.readProperties(in);
|
||||
Signature sig = new Signature();
|
||||
sig.readBytes(in);
|
||||
|
||||
// ok, nothing b0rked
|
||||
_destination = dest;
|
||||
_sequenceNum = seq;
|
||||
_preferredName = name;
|
||||
_serviceType = type;
|
||||
_options = opts;
|
||||
_signature = sig;
|
||||
}
|
||||
}
|
66
apps/myi2p/java/src/net/i2p/myi2p/address/Subscription.java
Normal file
66
apps/myi2p/java/src/net/i2p/myi2p/address/Subscription.java
Normal file
@ -0,0 +1,66 @@
|
||||
package net.i2p.myi2p.address;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
|
||||
/**
|
||||
* Contains the preferences for subscribing to a particular peer's address
|
||||
* book.
|
||||
*/
|
||||
public class Subscription {
|
||||
private I2PAppContext _context;
|
||||
private int _queryFrequencyMinutes;
|
||||
private long _lastQueryAttempt;
|
||||
private long _lastQuerySuccess;
|
||||
|
||||
/** no subscription more often than 4 times a day */
|
||||
public static final int MIN_FREQUENCY = 6*60*60*1000;
|
||||
|
||||
public Subscription(I2PAppContext context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/** how often do we want to query the peer (in minutes) */
|
||||
public int getQueryFrequencyMinutes() { return _queryFrequencyMinutes; }
|
||||
public void setQueryFrequencyMinutes(int freq) { _queryFrequencyMinutes = freq; }
|
||||
|
||||
/** when did we last successfully query the peer */
|
||||
public long getLastQuerySuccess() { return _lastQuerySuccess; }
|
||||
public void setLastQuerySuccess(long when) { _lastQuerySuccess = when; }
|
||||
|
||||
/** when did we last attempt to query the peer */
|
||||
public long getLastQueryAttempt() { return _lastQueryAttempt; }
|
||||
public void setLastQueryAttempt(long when) { _lastQueryAttempt = when; }
|
||||
|
||||
/** load the data from the stream */
|
||||
public void read(InputStream in) throws IOException {
|
||||
try {
|
||||
int freq = (int)DataHelper.readLong(in, 2);
|
||||
Date attempt = DataHelper.readDate(in);
|
||||
Date success = DataHelper.readDate(in);
|
||||
_queryFrequencyMinutes = (freq < MIN_FREQUENCY ? MIN_FREQUENCY : freq);
|
||||
_lastQueryAttempt = (attempt != null ? attempt.getTime() : -1);
|
||||
_lastQuerySuccess = (success != null ? success.getTime() : -1);
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt subscription: " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** persist the data to the stream */
|
||||
public void write(OutputStream out) throws IOException {
|
||||
try {
|
||||
DataHelper.writeLong(out, 2, _queryFrequencyMinutes);
|
||||
DataHelper.writeDate(out, new Date(_lastQueryAttempt));
|
||||
DataHelper.writeDate(out, new Date(_lastQuerySuccess));
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new IOException("Corrupt subscription: " + dfe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
3
apps/myi2p/myi2p.config
Normal file
3
apps/myi2p/myi2p.config
Normal file
@ -0,0 +1,3 @@
|
||||
keyFile=myi2p.keys
|
||||
service.0.classname=net.i2p.myi2p.address.AddressBookService
|
||||
service.0.type=AddressBook
|
180
apps/proxyscript/i2pProxy.pac
Normal file
180
apps/proxyscript/i2pProxy.pac
Normal file
@ -0,0 +1,180 @@
|
||||
/*******************************************************
|
||||
** Proxy Auto Configure Script with I2P Host Detection.
|
||||
**
|
||||
** Author: Cervantes
|
||||
** License: Public Domain
|
||||
** Date: 11 May 2004
|
||||
**
|
||||
** Revised: 07 Sep 2004
|
||||
** Changes:
|
||||
** Proxy recursion disabled by default (strict)
|
||||
** Password Authentication for session commands
|
||||
** Support for http://path?i2paddresshelper=BASE64
|
||||
** Support for http://i2p/BASE64/path syntax
|
||||
** Revised: 17 May 2004
|
||||
** Changes:
|
||||
** Ability for the user to control the proxy
|
||||
** status on a per browser-session basis.
|
||||
********************************************************/
|
||||
|
||||
|
||||
/* C O N F I G U R A T I O N
|
||||
*/
|
||||
|
||||
/* Replace normal with "PROXY yourproxy:port" if you run
|
||||
** behind a Proxy Server by default.
|
||||
*/
|
||||
var normal = "DIRECT";
|
||||
|
||||
/* Specify the I2P proxy connection details here.
|
||||
*/
|
||||
|
||||
var i2pProxy = "PROXY 127.0.0.1:4444";
|
||||
|
||||
/* Set the default status of proxy detection here:
|
||||
**
|
||||
**
|
||||
** [1] "auto" => Proxy will be used automatically if
|
||||
** '-> an ".i2p" url is detected.
|
||||
** '-> You will only be anonymous for ".i2p" domains.
|
||||
**
|
||||
** [2] "on" => Proxy is enabled all the time. (safest)
|
||||
** '-> NB. Normal web available only via
|
||||
** '-> i2p outproxies.
|
||||
** '-> You can be fairly confident of anonymity.
|
||||
**
|
||||
** [3] "off" => Completely Bypass the proxy and therefore i2p.
|
||||
** '-> no i2p sites will be accessible...
|
||||
** '-> ...your browsing habits can potentially
|
||||
** '-> be traced back to you!
|
||||
**
|
||||
*/
|
||||
|
||||
var proxyStatus = "auto";
|
||||
|
||||
/* By setting statusKeyword to "all" you can set these options at runtime
|
||||
** for the duration of the browser session by entering special commands
|
||||
** into your browser address bar.
|
||||
**
|
||||
** Due to limitations in the way proxy scripting works, a malicious site
|
||||
** could change your status mode by linking to command keywords...
|
||||
** eg. <img src="i2p.off" ...
|
||||
** This is why the default setting for statusKeyword is "limited", which only
|
||||
** allows you to set the proxy status to "on". See also keywordAuthPassword.
|
||||
**
|
||||
** [1] "all" => All proxy status urls are available.
|
||||
** '-> i2p.on, i2p.off, i2p.auto (respective to proxyStatus settings)
|
||||
** '-> WARNING: Setting "all" is a big risk to your anonymity!
|
||||
** '-> In this mode it is highly recommended you set an AuthPassword too!
|
||||
**
|
||||
** [2] "limited" => Only i2p.on is available..
|
||||
** '-> This setting lasts for the duration of the browser setting.
|
||||
** '-> You have to close your browser in order to revert to
|
||||
** '-> your default proxyStatus configuration.
|
||||
**
|
||||
** [3] "off" => No command urls available.
|
||||
** '-> The status mode can only be altered by editing the above
|
||||
** '-> proxyStatus setting. (safest)
|
||||
**
|
||||
*/
|
||||
|
||||
var statusKeyword = "all";
|
||||
|
||||
/*
|
||||
** By default if proxyStatus is set to "auto" the config script
|
||||
** will fall back to your normal connection settings if the
|
||||
** i2p proxy is offline. This is handy for browsing your locally
|
||||
** hosted eepsites when your router is not running (for instance).
|
||||
** However this can mean that requests to external eepsites could
|
||||
** be forwarded to the outweb and potentially compromise some of
|
||||
** your rights to anonymity.
|
||||
** Setting "true" here enables strict mode where all requests to ".i2p"
|
||||
** sites will be rejected if the i2p proxy is offline. (safest)
|
||||
*/
|
||||
|
||||
var strict = true;
|
||||
|
||||
/*
|
||||
** By setting an authentication password, all activated session keywords
|
||||
** will require the addition of a password to prevent malicious sites from
|
||||
** hijacking your proxy settings. ie. <img src="i2p.off" ...
|
||||
** Users should append whatever they set here to any command keywords
|
||||
** they use.
|
||||
** eg. i2p.on.passw0rd
|
||||
** If left blank, authentication is ignored - it is recommended that
|
||||
** you use "limited" statusKeyword mode if you choose not to require a password.
|
||||
** If you do require this feature then you should replace the default "passw0rd" with
|
||||
** one of your own (recommend at least 8 letters with a case-sensitive alpha-numeric
|
||||
** mix of characters).
|
||||
**
|
||||
*/
|
||||
|
||||
var keywordAuthPassword = "passw0rd";
|
||||
|
||||
|
||||
/* E N D C O N F I G U R A T I O N
|
||||
*/
|
||||
|
||||
|
||||
/* Allows the proxy to fallback on "normal" settings
|
||||
** '-> if the i2p router is offline.
|
||||
*/
|
||||
|
||||
if (strict == false) {
|
||||
i2pProxy = i2pProxy + "; " + normal;
|
||||
}
|
||||
|
||||
/*Check for User Authentication Password.
|
||||
*/
|
||||
if (keywordAuthPassword != "") {
|
||||
keywordAuthPassword = "." + keywordAuthPassword;
|
||||
}
|
||||
|
||||
/* This function gets called every time a url is submitted
|
||||
*/
|
||||
|
||||
function FindProxyForURL(url, host) {
|
||||
/* checks for a special command url that
|
||||
** '-> changes the status of the proxy script.
|
||||
*/
|
||||
|
||||
if (statusKeyword != "off") {
|
||||
if (host == "i2p.off" + keywordAuthPassword && statusKeyword == "all") {
|
||||
/*Proxy is bypassed - outweb available only
|
||||
*/
|
||||
proxyStatus = "off";
|
||||
} else if (host == "i2p.auto" + keywordAuthPassword && statusKeyword == "all") {
|
||||
/* Proxy is used only for .i2p hosts otherwise
|
||||
** '-> browse as normal.
|
||||
*/
|
||||
proxyStatus = "auto";
|
||||
} else if (host == "i2p.on" + keywordAuthPassword && (statusKeyword == "limited" ||
|
||||
statusKeyword == "all" )) {
|
||||
/* Only I2P traffic is accepted.
|
||||
*/
|
||||
proxyStatus = "on";
|
||||
}
|
||||
}
|
||||
|
||||
if (proxyStatus == "off") {
|
||||
/* Proxy is completely bypassed.
|
||||
*/
|
||||
return normal;
|
||||
} else if (proxyStatus == "on") {
|
||||
/* All requests are forward to the proxy.
|
||||
*/
|
||||
return i2pProxy;
|
||||
}
|
||||
|
||||
host = host.toLowerCase();
|
||||
/* check tld for "i2p" or oOo's new "i2paddresshelper" syntax - if found then redirect
|
||||
** '-> request to the i2p proxy
|
||||
*/
|
||||
|
||||
if (url.match(/^http:\/\/i2p\/[a-zA-Z0-9\-\~]{516}|i2paddresshelper=/i) ||
|
||||
shExpMatch(host, "*.i2p")) { // seems more reliable than:
|
||||
return i2pProxy; // dnsDomainIs(host, ".i2p") ||
|
||||
} else { // i2pRegex.test(host)
|
||||
return normal;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
<target name="build" depends="builddep, jar" />
|
||||
<target name="builddep">
|
||||
<ant dir="../../../router/java/" target="build" />
|
||||
<ant dir="../../systray/java/" target="build" />
|
||||
<!-- router will build core -->
|
||||
</target>
|
||||
<target name="prepare">
|
||||
@ -15,8 +16,16 @@
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true" deprecation="on" source="1.3" target="1.3"
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar:../../../router/java/build/router.jar:../../jetty/jettylib/org.mortbay.jetty-jdk1.2.jar" />
|
||||
destdir="./build/obj">
|
||||
<classpath>
|
||||
<pathelement location="../../../core/java/build/i2p.jar" />
|
||||
<pathelement location="../../../router/java/build/router.jar" />
|
||||
<pathelement location="../../jetty/jettylib/org.mortbay.jetty-jdk1.2.jar" />
|
||||
<pathelement location="../../systray/java/build/systray.jar" />
|
||||
<pathelement location="../../systray/java/lib/systray4j.jar" />
|
||||
<pathelement location="../../../installer/lib/wrapper/win32/wrapper.jar" /> <!-- we dont care if we're not on win32 -->
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class">
|
||||
@ -44,6 +53,8 @@
|
||||
<pathelement location="../../jetty/jettylib/jasper-runtime.jar" />
|
||||
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
|
||||
<pathelement location="../../jetty/jettylib/ant.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../../installer/lib/wrapper/win32/wrapper.jar" /> <!-- we dont care if we're not on win32 -->
|
||||
<pathelement location="build/routerconsole.jar" />
|
||||
</classpath>
|
||||
<arg value="-d" />
|
||||
@ -77,7 +88,7 @@
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/javadoc" />
|
||||
<javadoc
|
||||
sourcepath="./src:../../../core/java/src:../../router/java/src" destdir="./build/javadoc"
|
||||
sourcepath="./src:../../../core/java/src:../../../router/java/src:../../systray/java/src" destdir="./build/javadoc"
|
||||
packagenames="*"
|
||||
use="true"
|
||||
splitindex="true"
|
||||
@ -88,10 +99,12 @@
|
||||
</target>
|
||||
<target name="cleandep" depends="clean">
|
||||
<!-- router will clean core -->
|
||||
<ant dir="../../../router/java/" target="distclean" />
|
||||
<ant dir="../../../router/java/" target="cleandep" />
|
||||
<ant dir="../../systray/java/" target="cleandep" />
|
||||
</target>
|
||||
<target name="distclean" depends="clean">
|
||||
<!-- router will clean core -->
|
||||
<ant dir="../../../router/java/" target="distclean" />
|
||||
<ant dir="../../systray/java/" target="distclean" />
|
||||
</target>
|
||||
</project>
|
||||
|
@ -145,11 +145,16 @@ public class ConfigNetHandler extends FormHandler {
|
||||
}
|
||||
|
||||
int fetched = 0;
|
||||
int errors = 0;
|
||||
for (Iterator iter = urls.iterator(); iter.hasNext(); ) {
|
||||
fetchSeed(seedURL, (String)iter.next());
|
||||
fetched++;
|
||||
try {
|
||||
fetchSeed(seedURL, (String)iter.next());
|
||||
fetched++;
|
||||
} catch (Exception e) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
addFormNotice("Reseeded with " + fetched + " peers");
|
||||
addFormNotice("Reseeded with " + fetched + " peers (and " + errors + " failures)");
|
||||
} catch (Throwable t) {
|
||||
_context.logManager().getLog(ConfigNetHandler.class).error("Error reseeding", t);
|
||||
addFormError("Error reseeding (RESEED_EXCEPTION)");
|
||||
@ -157,7 +162,7 @@ public class ConfigNetHandler extends FormHandler {
|
||||
}
|
||||
|
||||
private void fetchSeed(String seedURL, String peer) throws Exception {
|
||||
URL url = new URL(seedURL + "/routerInfo-" + peer + ".dat");
|
||||
URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + "routerInfo-" + peer + ".dat");
|
||||
|
||||
byte data[] = readURL(url);
|
||||
writeSeed(peer, data);
|
||||
@ -222,9 +227,10 @@ public class ConfigNetHandler extends FormHandler {
|
||||
updateRates();
|
||||
|
||||
if (_timeSyncEnabled) {
|
||||
// Time sync enable, means NOT disabled
|
||||
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
|
||||
} else {
|
||||
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
|
||||
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "true");
|
||||
}
|
||||
|
||||
boolean saved = _context.router().saveConfig();
|
||||
|
@ -51,8 +51,8 @@ public class ConfigNetHelper {
|
||||
}
|
||||
|
||||
public String getEnableTimeSyncChecked() {
|
||||
String enabled = _context.getProperty(Timestamper.PROP_DISABLED, "true");
|
||||
if ( (enabled == null) || (!"true".equalsIgnoreCase(enabled)) )
|
||||
String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false");
|
||||
if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) )
|
||||
return "";
|
||||
else
|
||||
return " checked ";
|
||||
|
@ -0,0 +1,110 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.router.ClientTunnelSettings;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.apps.systray.SysTray;
|
||||
import org.tanukisoftware.wrapper.WrapperManager;
|
||||
|
||||
/**
|
||||
* Handler to deal with form submissions from the service config form and act
|
||||
* upon the values.
|
||||
*
|
||||
*/
|
||||
public class ConfigServiceHandler extends FormHandler {
|
||||
public void ConfigNetHandler() {}
|
||||
|
||||
private class UpdateWrapperManagerTask implements Runnable {
|
||||
private int _exitCode;
|
||||
public UpdateWrapperManagerTask(int exitCode) {
|
||||
_exitCode = exitCode;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
WrapperManager.signalStopped(_exitCode);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void processForm() {
|
||||
if (_action == null) return;
|
||||
|
||||
if ("Shutdown gracefully".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL));
|
||||
_context.router().shutdownGracefully();
|
||||
addFormNotice("Graceful shutdown initiated");
|
||||
} else if ("Shutdown immediately".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD));
|
||||
_context.router().shutdown(Router.EXIT_HARD);
|
||||
addFormNotice("Shutdown immediately! boom bye bye bad bwoy");
|
||||
} else if ("Cancel graceful shutdown".equals(_action)) {
|
||||
_context.router().cancelGracefulShutdown();
|
||||
addFormNotice("Graceful shutdown cancelled");
|
||||
} else if ("Graceful restart".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
addFormNotice("Graceful restart requested");
|
||||
} else if ("Hard restart".equals(_action)) {
|
||||
_context.router().addShutdownTask(new UpdateWrapperManagerTask(Router.EXIT_HARD_RESTART));
|
||||
_context.router().shutdown(Router.EXIT_HARD_RESTART);
|
||||
addFormNotice("Hard restart requested");
|
||||
} else if ("Run I2P on startup".equals(_action)) {
|
||||
installService();
|
||||
} else if ("Don't run I2P on startup".equals(_action)) {
|
||||
uninstallService();
|
||||
} else if ("Dump threads".equals(_action)) {
|
||||
try {
|
||||
WrapperManager.requestThreadDump();
|
||||
} catch (Throwable t) {
|
||||
addFormError("Warning: unable to contact the service manager - " + t.getMessage());
|
||||
}
|
||||
addFormNotice("Threads dumped to wrapper.log");
|
||||
} else if ("Show systray icon".equals(_action)) {
|
||||
try {
|
||||
SysTray tray = SysTray.getInstance();
|
||||
if (tray != null) {
|
||||
tray.show();
|
||||
addFormNotice("Systray enabled");
|
||||
} else {
|
||||
addFormNotice("Systray not supported on this platform");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
addFormError("Warning: unable to contact the systray manager - " + t.getMessage());
|
||||
}
|
||||
} else if ("Hide systray icon".equals(_action)) {
|
||||
try {
|
||||
SysTray tray = SysTray.getInstance();
|
||||
if (tray != null) {
|
||||
tray.hide();
|
||||
addFormNotice("Systray disabled");
|
||||
} else {
|
||||
addFormNotice("Systray not supported on this platform");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
addFormError("Warning: unable to contact the systray manager - " + t.getMessage());
|
||||
}
|
||||
} else {
|
||||
addFormNotice("Blah blah blah. whatever. I'm not going to " + _action);
|
||||
}
|
||||
}
|
||||
|
||||
private void installService() {
|
||||
try {
|
||||
Runtime.getRuntime().exec("install_i2p_service_winnt.bat");
|
||||
addFormNotice("Service installed");
|
||||
} catch (IOException ioe) {
|
||||
addFormError("Warning: unable to install the service - " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
private void uninstallService() {
|
||||
try {
|
||||
Runtime.getRuntime().exec("uninstall_i2p_service_winnt.bat");
|
||||
addFormNotice("Service removed");
|
||||
} catch (IOException ioe) {
|
||||
addFormError("Warning: unable to remove the service - " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
public class ContentHelper {
|
||||
private String _page;
|
||||
private int _maxLines;
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ContentHelper() {}
|
||||
|
||||
public void setPage(String page) { _page = page; }
|
||||
public void setMaxLines(String lines) {
|
||||
if (lines != null) {
|
||||
try {
|
||||
_maxLines = Integer.parseInt(lines);
|
||||
} catch (NumberFormatException nfe) {
|
||||
_maxLines = -1;
|
||||
}
|
||||
} else {
|
||||
_maxLines = -1;
|
||||
}
|
||||
}
|
||||
public String getContent() {
|
||||
String str = FileUtil.readTextFile(_page, _maxLines);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
return str;
|
||||
}
|
||||
public String getTextContent() {
|
||||
String str = FileUtil.readTextFile(_page, _maxLines);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
return "<pre>" + str + "</pre>";
|
||||
}
|
||||
}
|
@ -19,14 +19,20 @@ import net.i2p.router.ClientTunnelSettings;
|
||||
*/
|
||||
public class FormHandler {
|
||||
protected RouterContext _context;
|
||||
private String _nonce;
|
||||
protected String _action;
|
||||
private List _errors;
|
||||
private List _notices;
|
||||
private boolean _processed;
|
||||
private boolean _valid;
|
||||
|
||||
public FormHandler() {
|
||||
_errors = new ArrayList();
|
||||
_notices = new ArrayList();
|
||||
_action = null;
|
||||
_processed = false;
|
||||
_valid = true;
|
||||
_nonce = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,6 +49,9 @@ public class FormHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public void setNonce(String val) { _nonce = val; }
|
||||
public void setAction(String val) { _action = val; }
|
||||
|
||||
/**
|
||||
* Override this to perform the final processing (in turn, adding formNotice
|
||||
* and formError messages, etc)
|
||||
@ -72,6 +81,7 @@ public class FormHandler {
|
||||
*
|
||||
*/
|
||||
public String getErrors() {
|
||||
validate();
|
||||
return render(_errors);
|
||||
}
|
||||
|
||||
@ -81,12 +91,43 @@ public class FormHandler {
|
||||
*
|
||||
*/
|
||||
public String getNotices() {
|
||||
validate();
|
||||
return render(_notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the nonce was set correctly, otherwise someone could just
|
||||
* create a link like /confignet.jsp?hostname=localhost and break the
|
||||
* user's node (or worse).
|
||||
*
|
||||
*/
|
||||
private void validate() {
|
||||
if (_processed) return;
|
||||
|
||||
_valid = true;
|
||||
if (_action == null) {
|
||||
// not a form submit
|
||||
_valid = false;
|
||||
return;
|
||||
}
|
||||
if (_nonce == null) {
|
||||
addFormError("You trying to mess with me? Huh? Are you?");
|
||||
_valid = false;
|
||||
return;
|
||||
}
|
||||
String nonce = System.getProperty(getClass().getName() + ".nonce");
|
||||
String noncePrev = System.getProperty(getClass().getName() + ".noncePrev");
|
||||
if ( ( (nonce == null) || (!_nonce.equals(nonce)) ) &&
|
||||
( (noncePrev == null) || (!_nonce.equals(noncePrev)) ) ) {
|
||||
addFormError("Invalid nonce, are you being spoofed?");
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private String render(List source) {
|
||||
if (!_processed) {
|
||||
processForm();
|
||||
if (_valid)
|
||||
processForm();
|
||||
_processed = true;
|
||||
}
|
||||
if (source.size() <= 0) {
|
||||
|
@ -5,6 +5,7 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
public class LogsHelper {
|
||||
private RouterContext _context;
|
||||
@ -27,7 +28,31 @@ public class LogsHelper {
|
||||
public String getLogs() {
|
||||
List msgs = _context.logManager().getBuffer().getMostRecentMessages();
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h2>Most recent console messages:</h2><ul>");
|
||||
buf.append("<ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = msgs.size(); i > 0; i--) {
|
||||
String msg = (String)msgs.get(i - 1);
|
||||
buf.append("<li>");
|
||||
buf.append(msg);
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</code></ul>\n");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getServiceLogs() {
|
||||
String str = FileUtil.readTextFile("wrapper.log", 500);
|
||||
if (str == null)
|
||||
return "";
|
||||
else
|
||||
return "<pre>" + str + "</pre>";
|
||||
}
|
||||
|
||||
public String getConnectionLogs() {
|
||||
List msgs = _context.commSystem().getMostRecentErrorMessages();
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = msgs.size(); i > 0; i--) {
|
||||
String msg = (String)msgs.get(i - 1);
|
||||
|
@ -2,11 +2,14 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class NetDbHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -23,13 +26,21 @@ public class NetDbHelper {
|
||||
|
||||
public NetDbHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) { _out = writer; }
|
||||
|
||||
public String getNetDbSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
try {
|
||||
_context.netDb().renderStatusHTML(baos);
|
||||
if (_out != null) {
|
||||
_context.netDb().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
_context.netDb().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -9,6 +11,7 @@ import net.i2p.router.admin.StatsGenerator;
|
||||
|
||||
public class OldConsoleHelper {
|
||||
private RouterContext _context;
|
||||
private Writer _out;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -25,11 +28,20 @@ public class OldConsoleHelper {
|
||||
|
||||
public OldConsoleHelper() {}
|
||||
|
||||
public void setWriter(Writer writer) {
|
||||
_out = writer;
|
||||
}
|
||||
|
||||
public String getConsole() {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
_context.router().renderStatusHTML(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(128*1024);
|
||||
_context.router().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
@ -38,9 +50,14 @@ public class OldConsoleHelper {
|
||||
public String getStats() {
|
||||
StatsGenerator gen = new StatsGenerator(_context);
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(baos);
|
||||
return baos.toString();
|
||||
if (_out != null) {
|
||||
gen.generateStatsPage(_out);
|
||||
return "";
|
||||
} else {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
gen.generateStatsPage(new OutputStreamWriter(baos));
|
||||
return baos.toString();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return "<b>Error rending the console</b>";
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
@ -26,7 +27,7 @@ public class ProfilesHelper {
|
||||
public String getProfileSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(16*1024);
|
||||
try {
|
||||
_context.profileOrganizer().renderStatusHTML(baos);
|
||||
_context.profileOrganizer().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
@ -36,7 +37,7 @@ public class ProfilesHelper {
|
||||
public String getShitlistSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
|
||||
try {
|
||||
_context.shitlist().renderStatusHTML(baos);
|
||||
_context.shitlist().renderStatusHTML(new OutputStreamWriter(baos));
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.apps.systray.SysTray;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.http.DigestAuthenticator;
|
||||
import org.mortbay.http.handler.SecurityHandler;
|
||||
import org.mortbay.http.HashUserRealm;
|
||||
import org.mortbay.http.HttpRequest;
|
||||
@ -19,6 +23,10 @@ public class RouterConsoleRunner {
|
||||
private String _listenHost = "127.0.0.1";
|
||||
private String _webAppsDir = "./webapps/";
|
||||
|
||||
static {
|
||||
System.setProperty("org.mortbay.http.Version.paranoid", "true");
|
||||
}
|
||||
|
||||
public RouterConsoleRunner(String args[]) {
|
||||
if (args.length == 3) {
|
||||
_listenPort = args[0].trim();
|
||||
@ -33,6 +41,14 @@ public class RouterConsoleRunner {
|
||||
}
|
||||
|
||||
public void startConsole() {
|
||||
File workDir = new File("work");
|
||||
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
|
||||
if (!workDirRemoved)
|
||||
System.err.println("ERROR: Unable to remove Jetty temporary work directory");
|
||||
boolean workDirCreated = workDir.mkdirs();
|
||||
if (!workDirCreated)
|
||||
System.err.println("ERROR: Unable to create Jetty temporary work directory");
|
||||
|
||||
_server = new Server();
|
||||
WebApplicationContext contexts[] = null;
|
||||
try {
|
||||
@ -51,6 +67,11 @@ public class RouterConsoleRunner {
|
||||
} catch (MultiException me) {
|
||||
me.printStackTrace();
|
||||
}
|
||||
try {
|
||||
SysTray tray = SysTray.getInstance();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize(WebApplicationContext context) {
|
||||
@ -60,6 +81,7 @@ public class RouterConsoleRunner {
|
||||
realm.put("admin", password);
|
||||
realm.addUserToRole("admin", "routerAdmin");
|
||||
context.setRealm(realm);
|
||||
context.setAuthenticator(new DigestAuthenticator());
|
||||
context.addHandler(0, new SecurityHandler());
|
||||
SecurityConstraint constraint = new SecurityConstraint("admin", "routerAdmin");
|
||||
constraint.setAuthenticate(true);
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* I2P - An anonymous, secure, and fully-distributed communication network.
|
||||
*
|
||||
* ServiceManager.java
|
||||
* 2004 The I2P Project
|
||||
* http://www.i2p.net
|
||||
* This code is public domain.
|
||||
*/
|
||||
|
||||
package net.i2p.router.web;
|
||||
|
||||
//import java.io.InputStream;
|
||||
|
||||
import net.i2p.util.ShellCommand;
|
||||
|
||||
/**
|
||||
* Handles installation and uninstallation of I2P as a service.
|
||||
*
|
||||
* @author hypercubus
|
||||
*/
|
||||
public class ServiceManager {
|
||||
|
||||
private static final boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows") ? true : false;
|
||||
|
||||
private ShellCommand _shellCommand = new ShellCommand();
|
||||
|
||||
/**
|
||||
* Invokes the service wrapper installation script via a shell process.
|
||||
*
|
||||
* @return <code>null</code> if the installation was successful, otherwise
|
||||
* a <code>String</code> containing the shell output including error
|
||||
* messages is returned.
|
||||
*/
|
||||
public String installService() {
|
||||
return exec("install_i2p_service_" + (IS_WINDOWS ? "winnt.bat" : "unix"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the service wrapper uninstallation script via a shell process.
|
||||
*
|
||||
* @return <code>null</code> if the uninstallation was successful, otherwise
|
||||
* a <code>String</code> containing the shell output including error
|
||||
* messages is returned.
|
||||
*/
|
||||
public String uninstallService() {
|
||||
return exec("uninstall_i2p_service_" + (IS_WINDOWS ? "winnt.bat" : "unix"));
|
||||
}
|
||||
|
||||
private String exec(String command) {
|
||||
|
||||
// InputStream StdoutStream = _shellCommand.getInputStream();
|
||||
// InputStream StderrStream = _shellCommand.getErrorStream();
|
||||
StringBuffer result = null;
|
||||
|
||||
if (_shellCommand.executeAndWait(command))
|
||||
return null;
|
||||
|
||||
else
|
||||
if (result.toString().equals(""))
|
||||
return null;
|
||||
|
||||
else
|
||||
return result.toString();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
@ -49,7 +50,7 @@ public class SummaryHelper {
|
||||
*
|
||||
*/
|
||||
public String getVersion() {
|
||||
return RouterVersion.VERSION;
|
||||
return RouterVersion.VERSION + "-" + RouterVersion.BUILD;
|
||||
}
|
||||
/**
|
||||
* Retrieve a pretty printed uptime count (ala 4d or 7h or 39m)
|
||||
@ -78,10 +79,20 @@ public class SummaryHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* How many active peers the router has.
|
||||
* How many peers we are talking to now
|
||||
*
|
||||
*/
|
||||
public int getActivePeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.commSystem().countActivePeers();
|
||||
}
|
||||
/**
|
||||
* How many active identities have we spoken with recently
|
||||
*
|
||||
*/
|
||||
public int getActiveProfiles() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
@ -287,26 +298,27 @@ public class SummaryHelper {
|
||||
}
|
||||
|
||||
private static String getTransferred(long bytes) {
|
||||
double val = bytes;
|
||||
int scale = 0;
|
||||
if (bytes > 1024*1024*1024) {
|
||||
// gigs transferred
|
||||
scale = 3;
|
||||
bytes /= (1024*1024*1024);
|
||||
val /= (double)(1024*1024*1024);
|
||||
} else if (bytes > 1024*1024) {
|
||||
// megs transferred
|
||||
scale = 2;
|
||||
bytes /= (1024*1024);
|
||||
val /= (double)(1024*1024);
|
||||
} else if (bytes > 1024) {
|
||||
// kbytes transferred
|
||||
scale = 1;
|
||||
bytes /= 1024;
|
||||
val /= (double)1024;
|
||||
} else {
|
||||
scale = 0;
|
||||
}
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
String str = fmt.format(bytes);
|
||||
String str = fmt.format(val);
|
||||
switch (scale) {
|
||||
case 1: return str + "KB";
|
||||
case 2: return str + "MB";
|
||||
@ -323,7 +335,9 @@ public class SummaryHelper {
|
||||
public String getDestinations() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
_context.clientManager().renderStatusHTML(baos);
|
||||
OutputStreamWriter osw = new OutputStreamWriter(baos);
|
||||
_context.clientManager().renderStatusHTML(osw);
|
||||
osw.flush();
|
||||
return new String(baos.toByteArray());
|
||||
} catch (IOException ioe) {
|
||||
_context.logManager().getLog(SummaryHelper.class).error("Error rendering client info", ioe);
|
||||
@ -386,8 +400,7 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return ((int)delayRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getMessageDelay() + "ms";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -399,7 +412,6 @@ public class SummaryHelper {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return ((int)lagRate.getAverageValue()) + "ms";
|
||||
return _context.throttle().getTunnelLag() + "ms";
|
||||
}
|
||||
}
|
@ -22,6 +22,12 @@
|
||||
<i><jsp:getProperty name="formhandler" property="notices" /></i>
|
||||
|
||||
<form action="config.jsp" method="POST">
|
||||
<% String prev = System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce");
|
||||
if (prev != null) System.setProperty("net.i2p.router.web.ConfigNetHandler.noncePrev", prev);
|
||||
System.setProperty("net.i2p.router.web.ConfigNetHandler.nonce", new java.util.Random().nextLong()+""); %>
|
||||
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce")%>" />
|
||||
<input type="hidden" name="action" value="blah" />
|
||||
|
||||
<b>External hostname/IP address:</b>
|
||||
<input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" />
|
||||
<input type="submit" name="guesshost" value="Guess" /><br />
|
||||
@ -29,8 +35,11 @@
|
||||
<input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br />
|
||||
<i>The hostname/IP address and TCP port must be reachable from the outside world. If
|
||||
you are behind a firewall or NAT, this means you must poke a hole for this port. If
|
||||
you are using DHCP and do not have a static IP address, you must use a service like
|
||||
<a href="http://dyndns.org/">dyndns</a>. The "guess" functionality makes an HTTP request
|
||||
you are using DHCP and do not have a static IP address, you should either use a service like
|
||||
<a href="http://dyndns.org/">dyndns</a> or leave the hostname blank. If you leave it blank,
|
||||
your router will autodetect the 'correct' IP address by asking a peer (and unconditionally
|
||||
believing them if the address is routable and you don't have any established connections yet).
|
||||
The "guess" functionality makes an HTTP request
|
||||
to <a href="http://www.whatismyip.com/">www.whatismyip.com</a>.</i>
|
||||
<hr />
|
||||
<b>Enable internal time synchronization?</b> <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
|
||||
|
@ -23,6 +23,11 @@
|
||||
<i><jsp:getProperty name="formhandler" property="notices" /></i>
|
||||
|
||||
<form action="configadvanced.jsp" method="POST">
|
||||
<% String prev = System.getProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce");
|
||||
if (prev != null) System.setProperty("net.i2p.router.web.ConfigAdvancedHandler.noncePrev", prev);
|
||||
System.setProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce", new java.util.Random().nextLong()+""); %>
|
||||
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigAdvancedHandler.nonce")%>" />
|
||||
<input type="hidden" name="action" value="blah" />
|
||||
<textarea rows="20" cols="100" name="config"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br />
|
||||
<input type="submit" name="shouldsave" value="Apply" /> <input type="reset" value="Cancel" /> <br />
|
||||
<b>Force restart:</b> <input type="checkbox" name="restart" value="force" /> <i>(specify this
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user