forked from I2P_Developers/i2p.i2p
Compare commits
371 Commits
i2p_0_3_1_
...
i2p_0_3_4
Author | SHA1 | Date | |
---|---|---|---|
5d4bdc5697 | |||
0fdb286005 | |||
59a8493aa7 | |||
25378e894b | |||
3b9fea20b6 | |||
c6bb8f09ca | |||
4a9bd84bf0 | |||
c02522b0fe | |||
c2a71ef756 | |||
e669110cf4 | |||
f4cf31c13d | |||
7b23a5dcce | |||
b2fda0c79d | |||
5af96f5ccb | |||
ca445ac178 | |||
16fb31b6eb | |||
a1ff325b7b | |||
5eaec4c841 | |||
ffcc34c4f9 | |||
2dbe33e769 | |||
60c7db0733 | |||
0ed95bbdf1 | |||
c901bcf9b7 | |||
0ccf915a18 | |||
52b1c0a926 | |||
399865e6c8 | |||
54aeab1524 | |||
91f83277e2 | |||
c937cb2f07 | |||
ebd150e473 | |||
9218f7b82c | |||
edaf7aee5d | |||
43c18d0f4d | |||
65d85f7479 | |||
476e23db5b | |||
abaa5d87f6 | |||
ce3e7e623c | |||
3fd35a9c18 | |||
f170ae741e | |||
03562b037d | |||
472312709a | |||
b68463249e | |||
740a2da702 | |||
85c8e56417 | |||
481ef56e74 | |||
008795770f | |||
834fb7e317 | |||
da4827f287 | |||
9f4439583d | |||
69981e4d78 | |||
a857c6a88f | |||
e8d19439f8 | |||
56216250a7 | |||
bea331db26 | |||
bc4e833a47 | |||
83f399fffc | |||
5214436d18 | |||
8603250d73 | |||
9a8a099701 | |||
a5a0c8c837 | |||
604bcd5874 | |||
d29f9409bf | |||
b5a0f5910d | |||
ccb2600e67 | |||
f06e21ff5a | |||
bb0817a2ec | |||
6911f865ca | |||
fe28b2732c | |||
e8e8c37496 | |||
ef0f1ca1e7 | |||
31ca34b954 | |||
c4e6a2f0a8 | |||
b56845e200 | |||
d7a1fee781 | |||
b1f802c42d | |||
5f022e6e1f | |||
392cbb817e | |||
130399a1e7 | |||
37d5531737 | |||
f0b6cbaf89 | |||
707b173e77 | |||
4381bb5026 | |||
5850ad1217 | |||
806d598a04 | |||
e737e5c950 | |||
bbcde2f52b | |||
f6ef77429c | |||
44491c1514 | |||
71a6cf4ee6 | |||
744ce6966f | |||
d25cec02c2 | |||
f02bf37fd3 | |||
304b9d41d7 | |||
2d6af89f60 | |||
d6425973e2 | |||
d5ad56c4de | |||
4f1f2cc99e | |||
da439dd127 | |||
1375d01bdf | |||
7b9db07f13 | |||
f2f26136c1 | |||
0f60ac5acf | |||
c28f19fe8a | |||
09a6dbc755 | |||
3bc0e0fc8a | |||
eb0e187a54 | |||
a788d30f34 | |||
591dfc961e | |||
809e12b034 | |||
1669d174e1 | |||
3cfd28de43 | |||
4888207eca | |||
294cb96107 | |||
b648fa2b70 | |||
ab99122211 | |||
dd014fee88 | |||
c81f864de3 | |||
90fe7dceec | |||
3a568096f2 | |||
94e694fc61 | |||
bdfa6e4af5 | |||
8e64ffb4f6 | |||
6c162643cb | |||
ff7742bca3 | |||
9685884279 | |||
a8b0d7f999 | |||
dd84233085 | |||
fe3eac07f4 | |||
0948686989 | |||
4c82970319 | |||
fe2fede8ed | |||
b23b1e5f1f | |||
dca66c8de8 | |||
49090014cc | |||
fa4f100705 | |||
bbf68cd9a8 | |||
bbc5f6588a | |||
b3632a6a35 | |||
3943c51bb4 | |||
4c19ddde69 | |||
d8f0f1a1d3 | |||
121c0d89f2 | |||
badfb9088e | |||
ff392fee14 | |||
a13693161a | |||
4b8ac81669 | |||
219a704ee0 | |||
3996cd1f08 | |||
c636b0a0ec | |||
aae9f671f0 | |||
aec6e901ee | |||
f49be25288 | |||
f9a96126e1 | |||
8c9f58b939 | |||
8a7e787f42 | |||
148dcc084d | |||
15b1cbd762 | |||
e9b7ca3697 | |||
1b03e9a3ee | |||
2b951e3f61 | |||
f51e064cf6 | |||
9640e93895 | |||
d5bd22040c | |||
dcdcb7521a | |||
4058c63884 | |||
dd34548cc6 | |||
a6b5211fa7 | |||
4e89b9c363 | |||
f3e267d2d0 | |||
2fd87dc1f1 | |||
40b6b77cfa | |||
d0c61dbf4d | |||
1cd5a3fcf7 | |||
af81cf2c50 | |||
04373c5d1b | |||
e9cdb0f78d | |||
021b933ad3 | |||
9fd067c9da | |||
d3f3f3bdf7 | |||
72727dacd8 | |||
caeb2bc4e3 | |||
13974b601f | |||
cbc6aea8b4 | |||
290a2f7ccd | |||
349e80f206 | |||
5c1e001a73 | |||
f312318fab | |||
dc04b7cf09 | |||
77a8a46d8e | |||
95c7cd55c2 | |||
5f0ef5e0e8 | |||
1f26c603e0 | |||
7e2227ad42 | |||
9b4899da07 | |||
83c88ac0c6 | |||
44623065b4 | |||
47c7c8177d | |||
bde7a5ff59 | |||
a8ad8644c8 | |||
4e91bb88a5 | |||
f60a90e2da | |||
784dc0f6a7 | |||
e80e627fba | |||
d5987c51c9 | |||
5ced441b17 | |||
57801202fd | |||
a019399c3c | |||
e6f610a86c | |||
7ef528bbde | |||
a351a29bf3 | |||
983d258bce | |||
f6d38dd5e0 | |||
d51245aada | |||
56cf51f0f9 | |||
eb40fb9c5d | |||
085da0cea7 | |||
5539b19938 | |||
94feb762ca | |||
40b59d5a5a | |||
9ffd147470 | |||
3fea4ad2ba | |||
1ab5536879 | |||
9690a89a6d | |||
8f895f4349 | |||
980c0aa1d7 | |||
52fd6ca513 | |||
eb5dd2ff2e | |||
7ca35452eb | |||
dd781e256c | |||
551a7ab82f | |||
2901287d9e | |||
2b714967aa | |||
e8734ef1e7 | |||
14b9f9509f | |||
b1f973d304 | |||
2f17bfd71c | |||
b6670ee23a | |||
f1036df1f6 | |||
5c3e815757 | |||
55e780d885 | |||
d502df7d56 | |||
beb6cc8c0f | |||
c99db5e75c | |||
65cd70a85b | |||
5166eab5ee | |||
232f6f158d | |||
2a07ceba62 | |||
3e4b8c7dd4 | |||
26138e213f | |||
d82796e3ad | |||
cdcb81c867 | |||
5669e8f060 | |||
d84a40b4dc | |||
591be43763 | |||
97d0686354 | |||
e2da05b197 | |||
4f0052043d | |||
cfc1d1a2db | |||
9957e6ef17 | |||
6a02c8383c | |||
bc0a4ee68d | |||
1ca615da77 | |||
7da0cee29a | |||
f25bccd19f | |||
4e5a2e012c | |||
c9ee2a92a3 | |||
95a7938328 | |||
baedcdb2c1 | |||
bc06b3671a | |||
a9172811ca | |||
91b1fd6d07 | |||
bab7b8b9ed | |||
1b7fb96ca8 | |||
6d84b8c02f | |||
3e3749f011 | |||
52384fb3a5 | |||
e401670087 | |||
ae0b4c59cc | |||
0a8dc8afcc | |||
d59b94df66 | |||
e28502454b | |||
bbf73f0937 | |||
592519c45c | |||
cc904ba9dc | |||
1679ba6719 | |||
07fadd4a6c | |||
57e1ff39e0 | |||
51e259c198 | |||
de334b003d | |||
a61ff12390 | |||
f4697be159 | |||
3835fe3960 | |||
76c374ef06 | |||
57d24bd948 | |||
deff14dfd8 | |||
0a479be370 | |||
ba6a2e3fd2 | |||
c3a395a41e | |||
a3136a19e9 | |||
b631568003 | |||
1d0c03eca4 | |||
eb30525a26 | |||
3e66ea3f56 | |||
9f1189e606 | |||
698927bed4 | |||
8fd02ee8dd | |||
f3154e8f5e | |||
878af163a9 | |||
da8341d014 | |||
95c33e88ed | |||
fed8369a5f | |||
d85806e3d5 | |||
097660ce53 | |||
b08cfbbb35 | |||
97ee3c47a0 | |||
05918de6ab | |||
8d7abd8298 | |||
727f4c3bb5 | |||
7372ad0cc4 | |||
ca6884dbca | |||
1ebb0ac5fb | |||
bf0e53f13b | |||
8888a960c0 | |||
04be41aac5 | |||
fd1313d49f | |||
3599dba5c3 | |||
67edc437d2 | |||
7a39d9240c | |||
6d2d9aed7e | |||
3c2e5f22b6 | |||
ddb6348bfd | |||
d70c5df5a0 | |||
b2799d198c | |||
f2fa2038b1 | |||
bfd59e64ea | |||
60e05e270a | |||
242b9a6af9 | |||
e7e8ad9bdc | |||
0e5d164a8a | |||
7293a8d3c0 | |||
097a4647a8 | |||
0942a7f3ff | |||
2df4370477 | |||
7243963106 | |||
9f17654052 | |||
1a65d7061d | |||
292363eb65 | |||
07e79ce61a | |||
1cf7dac82b | |||
6003b2902f | |||
ff0023a889 | |||
8c6bf5a1cc | |||
61c97ab940 | |||
b0a1b3b5ca | |||
4c7af01edc | |||
0d431213cd | |||
ad9dd9a2e2 | |||
c7895ed905 | |||
57d7979d51 | |||
61f6871cd1 | |||
406048f7b9 | |||
6dd5b0fe45 | |||
fd4bc5e3cf | |||
3bab2d8957 | |||
af2f5cd2e1 | |||
d4bb32da82 | |||
08aca6ca61 | |||
697b3c6772 | |||
878525ced8 | |||
418531736b | |||
6c175440c6 |
27
apps/enclave/LICENSE
Normal file
27
apps/enclave/LICENSE
Normal file
@ -0,0 +1,27 @@
|
||||
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.
|
87
apps/enclave/Makefile.cygwin
Normal file
87
apps/enclave/Makefile.cygwin
Normal file
@ -0,0 +1,87 @@
|
||||
#
|
||||
# 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
|
87
apps/enclave/Makefile.linux
Normal file
87
apps/enclave/Makefile.linux
Normal file
@ -0,0 +1,87 @@
|
||||
#
|
||||
# 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
|
87
apps/enclave/Makefile.mingw
Normal file
87
apps/enclave/Makefile.mingw
Normal file
@ -0,0 +1,87 @@
|
||||
#
|
||||
# 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
|
32
apps/enclave/cfg/enclave.cfg
Normal file
32
apps/enclave/cfg/enclave.cfg
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# 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
|
2
apps/enclave/cfg/peers.ref
Normal file
2
apps/enclave/cfg/peers.ref
Normal file
@ -0,0 +1,2 @@
|
||||
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
|
27
apps/enclave/libsockthread/LICENSE
Normal file
27
apps/enclave/libsockthread/LICENSE
Normal file
@ -0,0 +1,27 @@
|
||||
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.
|
160
apps/enclave/libsockthread/src/logger.cpp
Normal file
160
apps/enclave/libsockthread/src/logger.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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
|
98
apps/enclave/libsockthread/src/logger.hpp
Normal file
98
apps/enclave/libsockthread/src/logger.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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
|
134
apps/enclave/libsockthread/src/mutex.cpp
Normal file
134
apps/enclave/libsockthread/src/mutex.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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
|
57
apps/enclave/libsockthread/src/mutex.hpp
Normal file
57
apps/enclave/libsockthread/src/mutex.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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
|
77
apps/enclave/libsockthread/src/platform.hpp
Normal file
77
apps/enclave/libsockthread/src/platform.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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
|
72
apps/enclave/libsockthread/src/socket.cpp
Normal file
72
apps/enclave/libsockthread/src/socket.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
68
apps/enclave/libsockthread/src/socket.hpp
Normal file
68
apps/enclave/libsockthread/src/socket.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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
|
108
apps/enclave/libsockthread/src/socket_addr.cpp
Normal file
108
apps/enclave/libsockthread/src/socket_addr.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
78
apps/enclave/libsockthread/src/socket_addr.hpp
Normal file
78
apps/enclave/libsockthread/src/socket_addr.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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
|
35
apps/enclave/libsockthread/src/socket_connector.cpp
Normal file
35
apps/enclave/libsockthread/src/socket_connector.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
46
apps/enclave/libsockthread/src/socket_connector.hpp
Normal file
46
apps/enclave/libsockthread/src/socket_connector.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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
|
47
apps/enclave/libsockthread/src/socket_error.hpp
Normal file
47
apps/enclave/libsockthread/src/socket_error.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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
|
35
apps/enclave/libsockthread/src/socket_listener.cpp
Normal file
35
apps/enclave/libsockthread/src/socket_listener.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
47
apps/enclave/libsockthread/src/socket_listener.hpp
Normal file
47
apps/enclave/libsockthread/src/socket_listener.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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
|
86
apps/enclave/libsockthread/src/strl.c
Normal file
86
apps/enclave/libsockthread/src/strl.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 */
|
||||
}
|
49
apps/enclave/libsockthread/src/strl.h
Normal file
49
apps/enclave/libsockthread/src/strl.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 */
|
194
apps/enclave/libsockthread/src/thread.cpp
Normal file
194
apps/enclave/libsockthread/src/thread.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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
|
69
apps/enclave/libsockthread/src/thread.hpp
Normal file
69
apps/enclave/libsockthread/src/thread.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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
|
85
apps/enclave/libsockthread/src/time.cpp
Normal file
85
apps/enclave/libsockthread/src/time.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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
|
55
apps/enclave/libsockthread/src/time.hpp
Normal file
55
apps/enclave/libsockthread/src/time.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
45
apps/enclave/libsockthread/src/types.hpp
Normal file
45
apps/enclave/libsockthread/src/types.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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
|
169
apps/enclave/src/bigint.cpp
Normal file
169
apps/enclave/src/bigint.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
60
apps/enclave/src/bigint.hpp
Normal file
60
apps/enclave/src/bigint.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
56
apps/enclave/src/chk.cpp
Normal file
56
apps/enclave/src/chk.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
51
apps/enclave/src/chk.hpp
Normal file
51
apps/enclave/src/chk.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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
|
148
apps/enclave/src/config.cpp
Normal file
148
apps/enclave/src/config.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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"));
|
||||
}
|
54
apps/enclave/src/config.hpp
Normal file
54
apps/enclave/src/config.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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
|
61
apps/enclave/src/logger.cpp
Normal file
61
apps/enclave/src/logger.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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
|
88
apps/enclave/src/logger.hpp
Normal file
88
apps/enclave/src/logger.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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
|
84
apps/enclave/src/main.cpp
Normal file
84
apps/enclave/src/main.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
36
apps/enclave/src/main.hpp
Normal file
36
apps/enclave/src/main.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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
|
54
apps/enclave/src/near_peer.hpp
Normal file
54
apps/enclave/src/near_peer.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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
|
52
apps/enclave/src/peer.hpp
Normal file
52
apps/enclave/src/peer.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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
|
220
apps/enclave/src/peers.cpp
Normal file
220
apps/enclave/src/peers.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
65
apps/enclave/src/peers.hpp
Normal file
65
apps/enclave/src/peers.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
|
111
apps/enclave/src/platform.hpp
Normal file
111
apps/enclave/src/platform.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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
|
65
apps/enclave/src/random.cpp
Normal file
65
apps/enclave/src/random.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
45
apps/enclave/src/random.hpp
Normal file
45
apps/enclave/src/random.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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
|
233
apps/enclave/src/rpc.cpp
Normal file
233
apps/enclave/src/rpc.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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";
|
||||
}
|
65
apps/enclave/src/rpc.hpp
Normal file
65
apps/enclave/src/rpc.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
|
249
apps/enclave/src/sam.cpp
Normal file
249
apps/enclave/src/sam.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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';
|
||||
}
|
||||
}
|
66
apps/enclave/src/sam.hpp
Normal file
66
apps/enclave/src/sam.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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
|
46
apps/enclave/src/sam_error.hpp
Normal file
46
apps/enclave/src/sam_error.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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
|
122
apps/enclave/src/sha1.cpp
Normal file
122
apps/enclave/src/sha1.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
56
apps/enclave/src/sha1.hpp
Normal file
56
apps/enclave/src/sha1.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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
|
@ -9,12 +9,12 @@
|
||||
<target name="compile">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac srcdir="./src" debug="true" destdir="./build/obj" includes="**/*.java" excludes="net/i2p/heartbeat/gui/**" classpath="../../../core/java/build/i2p.jar" />
|
||||
<javac srcdir="./src" debug="true" deprecation="on" source="1.3" target="1.3" destdir="./build/obj" includes="**/*.java" excludes="net/i2p/heartbeat/gui/**" classpath="../../../core/java/build/i2p.jar" />
|
||||
</target>
|
||||
<target name="compileGUI">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac debug="true" destdir="./build/obj">
|
||||
<javac debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj">
|
||||
<src path="src/" />
|
||||
<classpath path="../../../core/java/build/i2p.jar" />
|
||||
<classpath path="../../jfreechart/jfreechart-0.9.17/lib/jcommon-0.9.2.jar" />
|
||||
|
@ -358,7 +358,7 @@ public class ClientConfig {
|
||||
int sendFreq = getInt(sendFrequencyVal);
|
||||
int sendSize = getInt(sendSizeVal);
|
||||
|
||||
if ((duration <= 0) || (statFreq <= 0) || (sendFreq <= 0) || (sendSize <= 0)) {
|
||||
if ((duration <= 0) || (statFreq <= 0) || (sendFreq < 0) || (sendSize <= 0)) {
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
_log.warn("Invalid client config: duration [" + statDurationVal + "] stat frequency ["
|
||||
+ statFrequencyVal + "] send frequency [" + sendFrequencyVal + "] send size ["
|
||||
@ -424,7 +424,7 @@ public class ClientConfig {
|
||||
* @return true if it was stored correctly, false if there were errors
|
||||
*/
|
||||
public boolean store(Properties clientConfig, int peerNum) {
|
||||
if ((_peer == null) || (_sendFrequency <= 0) || (_sendSize <= 0) || (_statDuration <= 0)
|
||||
if ((_peer == null) || (_sendFrequency < 0) || (_sendSize <= 0) || (_statDuration <= 0)
|
||||
|| (_statFrequency <= 0) || (_statFile == null)) { return false; }
|
||||
|
||||
String comment = _comment;
|
||||
|
@ -4,7 +4,6 @@ import net.i2p.data.Destination;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
|
||||
/**
|
||||
* Responsible for actually conducting the tests, coordinating the storing of the
|
||||
@ -91,7 +90,7 @@ class ClientEngine {
|
||||
/** our actual heartbeat pumper - this drives the test */
|
||||
private class ClientRunner implements Runnable {
|
||||
|
||||
/* (non-Javadoc)
|
||||
/**
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
public void run() {
|
||||
@ -121,9 +120,12 @@ class ClientEngine {
|
||||
|
||||
_data.cleanup();
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {
|
||||
long timeToWait = nextSend - Clock.getInstance().now();
|
||||
if (timeToWait > 0) {
|
||||
try {
|
||||
Thread.sleep(timeToWait);
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ public class Heartbeat {
|
||||
}
|
||||
|
||||
/** disconnect from the network */
|
||||
private void disconnect() {
|
||||
private void disconnect() { /* UNUSED */
|
||||
_adapter.disconnect();
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
@ -46,7 +46,7 @@ class I2PAdapter {
|
||||
/** how do we talk to the router */
|
||||
private I2PSession _session;
|
||||
/** object that receives our i2cp notifications from the session and tells us */
|
||||
private I2PListener _i2pListener;
|
||||
private I2PListener _i2pListener; /* UNUSED */
|
||||
|
||||
/**
|
||||
* This config property tells us where the private destination data for our
|
||||
@ -219,7 +219,8 @@ class I2PAdapter {
|
||||
DataHelper.writeDate(baos, new Date(now));
|
||||
int padding = size - baos.size();
|
||||
byte paddingData[] = new byte[padding];
|
||||
Arrays.fill(paddingData, (byte) 0x2A);
|
||||
I2PAppContext.getGlobalContext().random().nextBytes(paddingData);
|
||||
//Arrays.fill(paddingData, (byte) 0x2A);
|
||||
DataHelper.writeLong(baos, 2, padding);
|
||||
baos.write(paddingData);
|
||||
boolean sent = _session.sendMessage(peer, baos.toByteArray());
|
||||
@ -577,14 +578,14 @@ class I2PAdapter {
|
||||
* @see net.i2p.client.I2PSessionListener#errorOccurred(net.i2p.client.I2PSession, java.lang.String, java.lang.Throwable)
|
||||
*/
|
||||
public void errorOccurred(I2PSession session, String message, Throwable error) {
|
||||
if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred", error);
|
||||
if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred: " + message, error);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see net.i2p.client.I2PSessionListener#reportAbuse(net.i2p.client.I2PSession, int)
|
||||
*/
|
||||
public void reportAbuse(I2PSession session, int severity) {
|
||||
if (_log.shouldLog(Log.ERROR)) _log.error("Abuse reported");
|
||||
if (_log.shouldLog(Log.ERROR)) _log.error("Abuse reported with severity " + String.valueOf(severity));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -600,4 +601,4 @@ class I2PAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package net.i2p.heartbeat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.stat.Rate;
|
||||
@ -27,7 +27,7 @@ public class PeerData {
|
||||
/** date sent (Long) to EventDataPoint containing the datapoints sent in the current period */
|
||||
private Map _dataPoints;
|
||||
/** date sent (Long) to EventDataPoint containing pings that haven't yet timed out or been ponged */
|
||||
private Map _pendingPings;
|
||||
private TreeMap _pendingPings;
|
||||
private long _sessionStart;
|
||||
private long _lifetimeSent;
|
||||
private long _lifetimeReceived;
|
||||
@ -103,6 +103,11 @@ public class PeerData {
|
||||
* @return when the test began
|
||||
*/
|
||||
public long getSessionStart() { return _sessionStart; }
|
||||
|
||||
/**
|
||||
* sets when the test began
|
||||
* @param when when it began
|
||||
*/
|
||||
public void setSessionStart(long when) { _sessionStart = when; }
|
||||
|
||||
/**
|
||||
@ -203,14 +208,32 @@ public class PeerData {
|
||||
public void pongReceived(long dateSent, long pongSent) {
|
||||
long now = Clock.getInstance().now();
|
||||
synchronized (_updateLock) {
|
||||
EventDataPoint data = (EventDataPoint) _pendingPings.remove(new Long(dateSent));
|
||||
if (_pendingPings.size() <= 0) {
|
||||
_log.warn("Pong received (sent at " + dateSent + ", " + (now-dateSent)
|
||||
+ "ms ago, pong delay " + (pongSent-dateSent) + "ms, pong receive delay "
|
||||
+ (now-pongSent) + "ms)");
|
||||
return;
|
||||
}
|
||||
Long first = (Long)_pendingPings.firstKey();
|
||||
EventDataPoint data = (EventDataPoint)_pendingPings.remove(new Long(dateSent));
|
||||
|
||||
if (data != null) {
|
||||
data.setPongReceived(now);
|
||||
data.setPongSent(pongSent);
|
||||
data.setWasPonged(true);
|
||||
locked_addDataPoint(data);
|
||||
|
||||
if (dateSent != first.longValue()) {
|
||||
_log.error("Out of order delivery: received " + dateSent
|
||||
+ " but the first pending is " + first.longValue()
|
||||
+ " (delta " + (dateSent - first.longValue()) + ")");
|
||||
} else {
|
||||
_log.info("In order delivery for " + dateSent + " in ping "
|
||||
+ _peer.getComment());
|
||||
}
|
||||
} else {
|
||||
_log.warn("Pong received, but no matching ping? ping sent at = " + dateSent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_sendRate.addData(pongSent - dateSent, 0);
|
||||
@ -332,6 +355,11 @@ public class PeerData {
|
||||
* @return the time the ping was sent
|
||||
*/
|
||||
public long getPingSent() { return _pingSent; }
|
||||
|
||||
/**
|
||||
* sets when we sent this ping
|
||||
* @param when when we sent the ping
|
||||
*/
|
||||
public void setPingSent(long when) { _pingSent = when; }
|
||||
|
||||
/**
|
||||
|
@ -114,7 +114,7 @@ public class PeerDataWriter {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static final SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd.HH:mm:ss.SSS", Locale.UK);
|
||||
private final SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd.HH:mm:ss.SSS", Locale.UK);
|
||||
|
||||
/**
|
||||
* Converts a time (long) to text
|
||||
@ -127,7 +127,7 @@ public class PeerDataWriter {
|
||||
}
|
||||
}
|
||||
|
||||
private static final DecimalFormat _numFmt = new DecimalFormat("#0", new DecimalFormatSymbols(Locale.UK));
|
||||
private final DecimalFormat _numFmt = new DecimalFormat("#0", new DecimalFormatSymbols(Locale.UK));
|
||||
|
||||
/**
|
||||
* Converts a number (double) to text
|
||||
|
@ -21,7 +21,7 @@ class HeartbeatControlPane extends JPanel {
|
||||
private HeartbeatMonitorGUI _gui;
|
||||
private JTabbedPane _configPane;
|
||||
private final static Color WHITE = new Color(255, 255, 255);
|
||||
private final static Color LIGHT_BLUE = new Color(180, 180, 255);
|
||||
private final static Color LIGHT_BLUE = new Color(180, 180, 255); /* UNUSED */
|
||||
private final static Color BLACK = new Color(0, 0, 0);
|
||||
private Color _background = WHITE;
|
||||
private Color _foreground = BLACK;
|
||||
|
@ -88,7 +88,9 @@ public class HeartbeatMonitor implements PeerPlotStateFetcher.FetchStateReceptor
|
||||
_gui.stateUpdated();
|
||||
}
|
||||
|
||||
/** store the config defining what peer tests we are monitoring (and how to render) */
|
||||
/**
|
||||
* store the config defining what peer tests we are monitoring (and how to render)
|
||||
*/
|
||||
void storeConfig() {}
|
||||
|
||||
/**
|
||||
@ -103,6 +105,10 @@ public class HeartbeatMonitor implements PeerPlotStateFetcher.FetchStateReceptor
|
||||
new HeartbeatMonitor().runMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the config is updated
|
||||
* @param config the updated config
|
||||
*/
|
||||
public void configUpdated(PeerPlotConfig config) {
|
||||
_log.debug("Config updated, revamping the gui");
|
||||
_gui.stateUpdated();
|
||||
|
@ -10,7 +10,6 @@ import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
|
||||
class HeartbeatMonitorGUI extends JFrame {
|
||||
private HeartbeatMonitor _monitor;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.i2p.heartbeat.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -1,28 +1,25 @@
|
||||
package net.i2p.heartbeat.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.util.List;
|
||||
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.DateAxis;
|
||||
import org.jfree.chart.axis.NumberAxis;
|
||||
import org.jfree.chart.plot.Plot;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.renderer.XYItemRenderer;
|
||||
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
|
||||
import org.jfree.data.XYSeries;
|
||||
import org.jfree.data.XYSeriesCollection;
|
||||
|
||||
import net.i2p.heartbeat.PeerData;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.jfree.data.XYSeries;
|
||||
import org.jfree.data.XYSeriesCollection;
|
||||
import org.jfree.data.MovingAverage;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
import org.jfree.chart.plot.Plot;
|
||||
import org.jfree.chart.plot.XYPlot;
|
||||
import org.jfree.chart.axis.DateAxis;
|
||||
import org.jfree.chart.axis.NumberAxis;
|
||||
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
|
||||
import org.jfree.chart.renderer.XYItemRenderer;
|
||||
import org.jfree.chart.renderer.XYDotRenderer;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.Font;
|
||||
import java.awt.Color;
|
||||
|
||||
class JFreeChartAdapter {
|
||||
private final static Log _log = new Log(JFreeChartAdapter.class);
|
||||
private final static Log _log = new Log(JFreeChartAdapter.class); /* UNUSED */
|
||||
private final static Color WHITE = new Color(255, 255, 255);
|
||||
|
||||
ChartPanel createPanel(HeartbeatMonitorState state) {
|
||||
@ -48,7 +45,7 @@ class JFreeChartAdapter {
|
||||
updateLines(plot, state);
|
||||
}
|
||||
|
||||
private long getFirst(HeartbeatMonitorState state) {
|
||||
private long getFirst(HeartbeatMonitorState state) { /* UNUSED */
|
||||
long first = -1;
|
||||
for (int i = 0; i < state.getTestCount(); i++) {
|
||||
List dataPoints = state.getTest(i).getCurrentData().getDataPoints();
|
||||
@ -119,6 +116,7 @@ class JFreeChartAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param col the collection of xy series to add to
|
||||
* @param config preferences for how to display this test
|
||||
* @param lineName minimal name of the test (e.g. "jxHa.32KB.60s")
|
||||
* @param data List of PeerData.EventDataPoint describing all of the events in the test
|
||||
@ -147,6 +145,7 @@ class JFreeChartAdapter {
|
||||
/**
|
||||
* Add a data series for each average that we're configured to render
|
||||
*
|
||||
* @param col the collection of xy series to add to
|
||||
* @param config preferences for how to display this test
|
||||
* @param lineName minimal name of the test (e.g. "jxHa.32KB.60s")
|
||||
* @param data List of PeerData.EventDataPoint describing all of the events in the test
|
||||
|
@ -1,34 +1,34 @@
|
||||
package net.i2p.heartbeat.gui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JLabel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.heartbeat.PeerDataWriter;
|
||||
import net.i2p.util.Log;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import org.jfree.chart.ChartPanel;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Render the graph and legend
|
||||
*
|
||||
*/
|
||||
class JFreeChartHeartbeatPlotPane extends HeartbeatPlotPane {
|
||||
private final static Log _log = new Log(JFreeChartHeartbeatPlotPane.class);
|
||||
private final static Log _log = new Log(JFreeChartHeartbeatPlotPane.class); /* UNUSED */
|
||||
private ChartPanel _panel;
|
||||
private JFreeChartAdapter _adapter;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a JFreeChart plot pane for the given gui
|
||||
* @param gui the heartbeat monitor gui
|
||||
*/
|
||||
public JFreeChartHeartbeatPlotPane(HeartbeatMonitorGUI gui) {
|
||||
super(gui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the state is updated
|
||||
*/
|
||||
public void stateUpdated() {
|
||||
if (_panel == null) {
|
||||
remove(0); // remove the dummy
|
||||
|
@ -11,14 +11,14 @@ import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.heartbeat.ClientConfig;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Configure how we want to render a particular clientConfig in the GUI
|
||||
*/
|
||||
class PeerPlotConfig {
|
||||
private final static Log _log = new Log(PeerPlotConfig.class);
|
||||
private final static Log _log = new Log(PeerPlotConfig.class); /* UNUSED */
|
||||
/** where can we find the current state/data (either as a filename or a URL)? */
|
||||
private String _location;
|
||||
/** what test are we defining the plot data for? */
|
||||
@ -170,8 +170,8 @@ class PeerPlotConfig {
|
||||
Destination peer = getClientConfig().getPeer();
|
||||
if (peer == null)
|
||||
return "????";
|
||||
else
|
||||
return peer.calculateHash().toBase64().substring(0, 4);
|
||||
|
||||
return peer.calculateHash().toBase64().substring(0, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,8 +196,8 @@ class PeerPlotConfig {
|
||||
int bytes = getClientConfig().getSendSize();
|
||||
if (bytes < 1024)
|
||||
return bytes + "b";
|
||||
else
|
||||
return bytes/1024 + "kb";
|
||||
|
||||
return bytes/1024 + "kb";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,6 +243,7 @@ class PeerPlotConfigPane extends JPanel implements PeerPlotConfig.UpdateListener
|
||||
_minutes = minutes;
|
||||
_button = button;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
||||
*/
|
||||
|
@ -326,7 +326,7 @@ class PeerPlotStateFetcher {
|
||||
}
|
||||
}
|
||||
|
||||
private void fakeRun() {
|
||||
private void fakeRun() { /* UNUSED */
|
||||
try {
|
||||
Destination peer = new Destination();
|
||||
Destination us = new Destination();
|
||||
|
@ -94,8 +94,8 @@ class StaticPeerData extends PeerData {
|
||||
Integer i = (Integer)_averageSendTimes.get(new Integer(period));
|
||||
if (i == null)
|
||||
return -1;
|
||||
else
|
||||
return i.doubleValue();
|
||||
|
||||
return i.doubleValue();
|
||||
}
|
||||
|
||||
|
||||
@ -109,8 +109,8 @@ class StaticPeerData extends PeerData {
|
||||
Integer i = (Integer)_averageReceiveTimes.get(new Integer(period));
|
||||
if (i == null)
|
||||
return -1;
|
||||
else
|
||||
return i.doubleValue();
|
||||
|
||||
return i.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,8 +123,8 @@ class StaticPeerData extends PeerData {
|
||||
Integer i = (Integer)_lostMessages.get(new Integer(period));
|
||||
if (i == null)
|
||||
return -1;
|
||||
else
|
||||
return i.doubleValue();
|
||||
|
||||
return i.doubleValue();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -11,7 +11,7 @@
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true"
|
||||
debug="true" deprecation="on" source="1.3" target="1.3"
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
|
||||
</target>
|
||||
|
@ -57,14 +57,14 @@ public class HTTPListener extends Thread {
|
||||
* @return Whether this is the first proxy use, no doubt.
|
||||
*/
|
||||
public boolean firstProxyUse() {
|
||||
// FIXME: check a config option here
|
||||
if (true) return false;
|
||||
if (true) return false; // FIXME: check a config option here
|
||||
|
||||
if (proxyUsed) {
|
||||
return false;
|
||||
} else {
|
||||
proxyUsed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
proxyUsed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,8 +7,8 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.SocketException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
@ -19,7 +19,6 @@ import net.i2p.httptunnel.SocketManagerProducer;
|
||||
import net.i2p.httptunnel.filter.Filter;
|
||||
import net.i2p.httptunnel.filter.NullFilter;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
/**
|
||||
* Handler for browsing Eepsites.
|
||||
|
@ -12,7 +12,7 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class ErrorHandler {
|
||||
|
||||
private static final Log _log = new Log(ErrorHandler.class);
|
||||
private static final Log _log = new Log(ErrorHandler.class); /* UNUSED */
|
||||
|
||||
/* package private */ErrorHandler() {
|
||||
|
||||
|
@ -13,7 +13,7 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class LocalHandler {
|
||||
|
||||
private static final Log _log = new Log(LocalHandler.class);
|
||||
private static final Log _log = new Log(LocalHandler.class); /* UNUSED */
|
||||
|
||||
/* package private */LocalHandler() {
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.i2p.httptunnel.handler;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.httptunnel.HTTPListener;
|
||||
@ -12,14 +12,13 @@ import net.i2p.httptunnel.SocketManagerProducer;
|
||||
import net.i2p.httptunnel.filter.Filter;
|
||||
import net.i2p.httptunnel.filter.NullFilter;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
/**
|
||||
* Handler for proxying "normal" HTTP requests.
|
||||
*/
|
||||
public class ProxyHandler extends EepHandler {
|
||||
|
||||
private static final Log _log = new Log(ErrorHandler.class);
|
||||
private static final Log _log = new Log(ErrorHandler.class); /* UNUSED */
|
||||
private static I2PAppContext _context = new I2PAppContext();
|
||||
|
||||
/* package private */ProxyHandler(ErrorHandler eh) {
|
||||
|
@ -12,7 +12,7 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
public class RootHandler {
|
||||
|
||||
private static final Log _log = new Log(RootHandler.class);
|
||||
private static final Log _log = new Log(RootHandler.class); /* UNUSED */
|
||||
|
||||
private RootHandler() {
|
||||
errorHandler = new ErrorHandler();
|
||||
@ -60,26 +60,24 @@ public class RootHandler {
|
||||
url = url.substring(7);
|
||||
pos = url.indexOf("/");
|
||||
String host;
|
||||
String rest;
|
||||
|
||||
if (pos == -1) {
|
||||
errorHandler.handle(req, httpl, out, "No host end in URL");
|
||||
return;
|
||||
}
|
||||
|
||||
host = url.substring(0, pos);
|
||||
url = url.substring(pos);
|
||||
if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
|
||||
// normal request; go on below...
|
||||
} else if (host.endsWith(".i2p")) {
|
||||
// "old" service request, send a redirect...
|
||||
out.write(("HTTP/1.1 302 Moved\r\nLocation: " + "http://i2p.i2p/" + host + url + "\r\n\r\n").getBytes("ISO-8859-1"));
|
||||
return;
|
||||
} else {
|
||||
host = url.substring(0, pos);
|
||||
url = url.substring(pos);
|
||||
if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
|
||||
// normal request; go on below...
|
||||
} else if (host.endsWith(".i2p")) {
|
||||
// "old" service request, send a redirect...
|
||||
out
|
||||
.write(("HTTP/1.1 302 Moved\r\nLocation: " + "http://i2p.i2p/" + host + url + "\r\n\r\n")
|
||||
.getBytes("ISO-8859-1"));
|
||||
return;
|
||||
} else {
|
||||
// this is for proxying to the real web
|
||||
proxyHandler.handle(req, httpl, out /*, true */);
|
||||
return;
|
||||
}
|
||||
// this is for proxying to the real web
|
||||
proxyHandler.handle(req, httpl, out /*, true */);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (url.equals("/")) { // main page
|
||||
|
@ -11,7 +11,7 @@
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true"
|
||||
debug="true" deprecation="on" source="1.3" target="1.3"
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
|
||||
</target>
|
||||
|
@ -17,6 +17,9 @@ class BufferLogger implements Logging {
|
||||
private ByteArrayOutputStream _baos;
|
||||
private boolean _ignore;
|
||||
|
||||
/**
|
||||
* Constructs a buffered logger.
|
||||
*/
|
||||
public BufferLogger() {
|
||||
_baos = new ByteArrayOutputStream(512);
|
||||
_ignore = false;
|
||||
@ -24,11 +27,15 @@ class BufferLogger implements Logging {
|
||||
|
||||
private final static String EMPTY = "";
|
||||
|
||||
/**
|
||||
* Retrieves the buffer
|
||||
* @return the buffer
|
||||
*/
|
||||
public String getBuffer() {
|
||||
if (_ignore)
|
||||
return EMPTY;
|
||||
else
|
||||
return new String(_baos.toByteArray());
|
||||
|
||||
return new String(_baos.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,6 +46,7 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
@ -67,6 +68,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
private Log _log;
|
||||
private EventDispatcherImpl _event;
|
||||
private I2PAppContext _context;
|
||||
private static long __tunnelId = 0;
|
||||
private long _tunnelId;
|
||||
private Properties _clientOptions;
|
||||
|
||||
public static final int PACKET_DELAY = 100;
|
||||
|
||||
@ -98,9 +102,13 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
}
|
||||
|
||||
public I2PTunnel(String[] args, ConnectionEventListener lsnr) {
|
||||
_context = new I2PAppContext();
|
||||
_context = I2PAppContext.getGlobalContext(); // new I2PAppContext();
|
||||
_tunnelId = ++__tunnelId;
|
||||
_log = _context.logManager().getLog(I2PTunnel.class);
|
||||
_event = new EventDispatcherImpl();
|
||||
_clientOptions = new Properties();
|
||||
_clientOptions.putAll(System.getProperties());
|
||||
|
||||
addConnectionEventListener(lsnr);
|
||||
boolean gui = true;
|
||||
boolean checkRunByE = true;
|
||||
@ -114,7 +122,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
checkRunByE = false;
|
||||
} else if (args[i].equals("-nogui")) {
|
||||
gui = false;
|
||||
_log.warn("The `-nogui' option of I2PTunnel is deprecated.\n"
|
||||
_log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
|
||||
+ "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
|
||||
} else if (args[i].equals("-cli")) {
|
||||
gui = false;
|
||||
@ -164,6 +172,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
public Properties getClientOptions() { return _clientOptions; }
|
||||
|
||||
private void addtask(I2PTunnelTask tsk) {
|
||||
tsk.setTunnel(this);
|
||||
if (tsk.isOpen()) {
|
||||
@ -194,6 +204,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
|
||||
if ("help".equals(cmdname)) {
|
||||
runHelp(l);
|
||||
} else if ("clientoptions".equals(cmdname)) {
|
||||
runClientOptions(args, l);
|
||||
} else if ("server".equals(cmdname)) {
|
||||
runServer(args, l);
|
||||
} else if ("textserver".equals(cmdname)) {
|
||||
@ -259,6 +271,29 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
l.log("list");
|
||||
l.log("run <commandfile>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the extra I2CP options to use in any subsequent I2CP sessions.
|
||||
* Usage: "clientoptions[ key=value]*" .
|
||||
*
|
||||
* Sets the event "clientoptions_onResult" = "ok" after completion.
|
||||
*
|
||||
* @param args each args[i] is a key=value pair to add to the options
|
||||
* @param l logger to receive events and output
|
||||
*/
|
||||
public void runClientOptions(String args[], Logging l) {
|
||||
_clientOptions.clear();
|
||||
if (args != null) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
int index = args[i].indexOf('=');
|
||||
if (index <= 0) continue;
|
||||
String key = args[i].substring(0, index);
|
||||
String val = args[i].substring(index+1);
|
||||
_clientOptions.setProperty(key, val);
|
||||
}
|
||||
}
|
||||
notifyEvent("clientoptions_onResult", "ok");
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the server pointing at the host and port specified using the private i2p
|
||||
@ -280,7 +315,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
serverHost = InetAddress.getByName(args[0]);
|
||||
} catch (UnknownHostException uhe) {
|
||||
l.log("unknown host");
|
||||
_log.error("Error resolving " + args[0], uhe);
|
||||
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
@ -289,7 +324,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
portNum = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
l.log("invalid port");
|
||||
_log.error("Port specified is not valid: " + args[1], nfe);
|
||||
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
@ -297,11 +332,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
privKeyFile = new File(args[2]);
|
||||
if (!privKeyFile.canRead()) {
|
||||
l.log("private key file does not exist");
|
||||
_log.error("Private key file does not exist or is not readable: " + args[2]);
|
||||
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this, this);
|
||||
serv.setReadTimeout(readTimeout);
|
||||
serv.startRunning();
|
||||
addtask(serv);
|
||||
@ -333,7 +368,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
serverHost = InetAddress.getByName(args[0]);
|
||||
} catch (UnknownHostException uhe) {
|
||||
l.log("unknown host");
|
||||
_log.error("Error resolving " + args[0], uhe);
|
||||
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
@ -342,12 +377,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
portNum = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
l.log("invalid port");
|
||||
_log.error("Port specified is not valid: " + args[1], nfe);
|
||||
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
|
||||
notifyEvent("serverTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
|
||||
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this, this);
|
||||
serv.setReadTimeout(readTimeout);
|
||||
serv.startRunning();
|
||||
addtask(serv);
|
||||
@ -378,12 +413,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
port = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
l.log("invalid port");
|
||||
_log.error("Port specified is not valid: " + args[0], nfe);
|
||||
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
|
||||
notifyEvent("clientTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
I2PTunnelTask task;
|
||||
task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this);
|
||||
task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this, this);
|
||||
addtask(task);
|
||||
notifyEvent("clientTaskId", new Integer(task.getId()));
|
||||
} else {
|
||||
@ -410,7 +445,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
port = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
l.log("invalid port");
|
||||
_log.error("Port specified is not valid: " + args[0], nfe);
|
||||
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
|
||||
notifyEvent("httpclientTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
@ -420,7 +455,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
proxy = args[1];
|
||||
}
|
||||
I2PTunnelTask task;
|
||||
task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this);
|
||||
task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this, this);
|
||||
addtask(task);
|
||||
notifyEvent("httpclientTaskId", new Integer(task.getId()));
|
||||
} else {
|
||||
@ -451,13 +486,13 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
port = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
l.log("invalid port");
|
||||
_log.error("Port specified is not valid: " + args[0], nfe);
|
||||
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
|
||||
notifyEvent("sockstunnelTaskId", new Integer(-1));
|
||||
return;
|
||||
}
|
||||
|
||||
I2PTunnelTask task;
|
||||
task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this);
|
||||
task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this, this);
|
||||
addtask(task);
|
||||
notifyEvent("sockstunnelTaskId", new Integer(task.getId()));
|
||||
} else {
|
||||
@ -565,7 +600,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
pubdest = new FileOutputStream(args[1]);
|
||||
} catch (IOException ioe) {
|
||||
l.log("Error opening output stream");
|
||||
_log.error("Error generating keys to out", ioe);
|
||||
_log.error(getPrefix() + "Error generating keys to out", ioe);
|
||||
notifyEvent("genkeysResult", "error");
|
||||
return;
|
||||
}
|
||||
@ -588,7 +623,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
} catch (IOException ioe) {
|
||||
l.log("Error generating keys - " + ioe.getMessage());
|
||||
notifyEvent("genkeysResult", "error");
|
||||
_log.error("Error generating keys", ioe);
|
||||
_log.error(getPrefix() + "Error generating keys", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,7 +757,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
notifyEvent("runResult", "ok");
|
||||
} catch (IOException ioe) {
|
||||
l.log("IO error running the file");
|
||||
_log.error("Error running the file", ioe);
|
||||
_log.error(getPrefix() + "Error running the file", ioe);
|
||||
notifyEvent("runResult", "error");
|
||||
}
|
||||
} else {
|
||||
@ -776,7 +811,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
if (allargs.length() != 0) {
|
||||
I2PTunnelTask task;
|
||||
// pings always use the main destination
|
||||
task = new I2Ping(allargs, l, false, (EventDispatcher) this);
|
||||
task = new I2Ping(allargs, l, false, (EventDispatcher) this, this);
|
||||
addtask(task);
|
||||
notifyEvent("pingTaskId", new Integer(task.getId()));
|
||||
} else {
|
||||
@ -796,12 +831,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
private boolean closetask(int num, boolean forced, Logging l) {
|
||||
boolean closed = false;
|
||||
|
||||
_log.debug("closetask(): looking for task " + num);
|
||||
_log.debug(getPrefix() + "closetask(): looking for task " + num);
|
||||
synchronized (tasks) {
|
||||
for (Iterator it = tasks.iterator(); it.hasNext();) {
|
||||
I2PTunnelTask t = (I2PTunnelTask) it.next();
|
||||
int id = t.getId();
|
||||
_log.debug("closetask(): parsing task " + id + " (" + t.toString() + ")");
|
||||
_log.debug(getPrefix() + "closetask(): parsing task " + id + " (" + t.toString() + ")");
|
||||
if (id == num) {
|
||||
closed = closetask(t, forced, l);
|
||||
break;
|
||||
@ -836,7 +871,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
for (Iterator it = tasks.iterator(); it.hasNext();) {
|
||||
I2PTunnelTask t = (I2PTunnelTask) it.next();
|
||||
if (!t.isOpen()) {
|
||||
_log.debug("Purging inactive tunnel: [" + t.getId() + "] " + t.toString());
|
||||
_log.debug(getPrefix() + "Purging inactive tunnel: [" + t.getId() + "] " + t.toString());
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
@ -849,7 +884,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
*/
|
||||
public void log(String s) {
|
||||
System.out.println(s);
|
||||
_log.info("Display: " + s);
|
||||
_log.info(getPrefix() + "Display: " + s);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -982,6 +1017,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
listeners.remove(lsnr);
|
||||
}
|
||||
}
|
||||
|
||||
private String getPrefix() { return '[' + _tunnelId + "]: "; }
|
||||
|
||||
/**
|
||||
* Call this whenever we lose touch with the router involuntarily (aka the router
|
||||
@ -989,7 +1026,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
*
|
||||
*/
|
||||
void routerDisconnected() {
|
||||
_log.error("Router disconnected - firing notification events");
|
||||
_log.error(getPrefix() + "Router disconnected - firing notification events");
|
||||
synchronized (listeners) {
|
||||
for (Iterator iter = listeners.iterator(); iter.hasNext();) {
|
||||
ConnectionEventListener lsnr = (ConnectionEventListener) iter.next();
|
||||
|
@ -5,7 +5,6 @@ package net.i2p.i2ptunnel;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
@ -20,8 +19,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
|
||||
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
|
||||
protected long readTimeout = DEFAULT_READ_TIMEOUT;
|
||||
|
||||
public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis) {
|
||||
super(localPort, ownDest, l, notifyThis, "SynSender");
|
||||
public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(localPort, ownDest, l, notifyThis, "SynSender", tunnel);
|
||||
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
notifyEvent("openClientResult", "error");
|
||||
|
@ -34,7 +34,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
private static final long DEFAULT_CONNECT_TIMEOUT = 60 * 1000;
|
||||
|
||||
private static volatile long __clientId = 0;
|
||||
private long _clientId;
|
||||
protected long _clientId;
|
||||
protected Object sockLock = new Object(); // Guards sockMgr and mySockets
|
||||
private I2PSocketManager sockMgr;
|
||||
private List mySockets = new ArrayList();
|
||||
@ -60,8 +60,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
// I2PTunnelClientBase(localPort, ownDest, l, (EventDispatcher)null);
|
||||
//}
|
||||
|
||||
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName) {
|
||||
super(localPort + " (uninitialized)", notifyThis);
|
||||
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName, I2PTunnel tunnel) {
|
||||
super(localPort + " (uninitialized)", notifyThis, tunnel);
|
||||
_clientId = ++__clientId;
|
||||
this.localPort = localPort;
|
||||
this.l = l;
|
||||
@ -103,17 +103,28 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
private static I2PSocketManager socketManager;
|
||||
|
||||
protected static synchronized I2PSocketManager getSocketManager() {
|
||||
protected synchronized I2PSocketManager getSocketManager() {
|
||||
return getSocketManager(getTunnel());
|
||||
}
|
||||
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
|
||||
if (socketManager == null) {
|
||||
socketManager = buildSocketManager();
|
||||
socketManager = buildSocketManager(tunnel);
|
||||
}
|
||||
return socketManager;
|
||||
}
|
||||
|
||||
protected static I2PSocketManager buildSocketManager() {
|
||||
protected I2PSocketManager buildSocketManager() {
|
||||
return buildSocketManager(getTunnel());
|
||||
}
|
||||
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel) {
|
||||
Properties props = new Properties();
|
||||
props.putAll(System.getProperties());
|
||||
return I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
|
||||
if (tunnel == null)
|
||||
props.putAll(System.getProperties());
|
||||
else
|
||||
props.putAll(tunnel.getClientOptions());
|
||||
I2PSocketManager sockManager = I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
|
||||
sockManager.setName("Client");
|
||||
return sockManager;
|
||||
}
|
||||
|
||||
public final int getLocalPort() {
|
||||
|
@ -10,9 +10,6 @@ import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
@ -48,7 +45,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
private String wwwProxy;
|
||||
|
||||
private final static byte[] ERR_REQUEST_DENIED =
|
||||
("HTTP/1.1 404 Not Found\r\n"+
|
||||
("HTTP/1.1 403 Access Denied\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
"Cache-control: no-cache\r\n"+
|
||||
"\r\n"+
|
||||
@ -57,24 +54,24 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
.getBytes();
|
||||
|
||||
private final static byte[] ERR_DESTINATION_UNKNOWN =
|
||||
("HTTP/1.1 404 Not Found\r\n"+
|
||||
("HTTP/1.1 503 Service Unavailable\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
"Cache-control: no-cache\r\n"+
|
||||
"\r\n"+
|
||||
"<html><body><H1>I2P ERROR: NOT FOUND</H1>"+
|
||||
"That Desitination was not found. Perhaps you pasted in the wrong "+
|
||||
"BASE64 I2P Destination or the link you are following is bad. "+
|
||||
"The host (or the WWW proxy, if you're using one) could also be "+
|
||||
"temporarily offline. You may want to <b>retry</b>. "+
|
||||
"<html><body><H1>I2P ERROR: DESTINATION NOT FOUND</H1>"+
|
||||
"That I2P Destination was not found. Perhaps you pasted in the "+
|
||||
"wrong BASE64 I2P Destination or the link you are following is "+
|
||||
"bad. The host (or the WWW proxy, if you're using one) could also "+
|
||||
"be temporarily offline. You may want to <b>retry</b>. "+
|
||||
"Could not find the following Destination:<BR><BR>")
|
||||
.getBytes();
|
||||
|
||||
private final static byte[] ERR_TIMEOUT =
|
||||
("HTTP/1.1 404 Not Found\r\n"+
|
||||
("HTTP/1.1 504 Gateway Timeout\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
"Cache-control: no-cache\r\n\r\n"+
|
||||
"<html><body><H1>I2P ERROR: TIMEOUT</H1>"+
|
||||
"That Desitination was reachable, but timed out getting a "+
|
||||
"That Destination was reachable, but timed out getting a "+
|
||||
"response. This is likely a temporary error, so you should simply "+
|
||||
"try to refresh, though if the problem persists, the remote "+
|
||||
"destination may have issues. Could not get a response from "+
|
||||
@ -84,8 +81,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
/** used to assign unique IDs to the threads / clients. no logic or functionality */
|
||||
private static volatile long __clientId = 0;
|
||||
|
||||
public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis) {
|
||||
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId));
|
||||
public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
|
||||
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
notifyEvent("openHTTPClientResult", "error");
|
||||
@ -101,6 +98,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
notifyEvent("openHTTPClientResult", "ok");
|
||||
}
|
||||
|
||||
private String getPrefix() { return "Client[" + _clientId + "]: "; }
|
||||
|
||||
protected void clientConnectionRun(Socket s) {
|
||||
OutputStream out = null;
|
||||
String targetRequest = null;
|
||||
@ -113,7 +112,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
StringBuffer newRequest = new StringBuffer();
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Line=[" + line + "]");
|
||||
_log.debug(getPrefix() + "Line=[" + line + "]");
|
||||
|
||||
if (line.startsWith("Connection: ") ||
|
||||
line.startsWith("Keep-Alive: ") ||
|
||||
@ -122,13 +121,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
if (method == null) { // first line (GET /base64/realaddr)
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Method is null for [" + line + "]");
|
||||
_log.debug(getPrefix() + "Method is null for [" + line + "]");
|
||||
|
||||
int pos = line.indexOf(" ");
|
||||
if (pos == -1) break;
|
||||
method = line.substring(0, pos);
|
||||
String request = line.substring(pos + 1);
|
||||
if (request.startsWith("/") && System.getProperty("i2ptunnel.noproxy") != null) {
|
||||
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
|
||||
request = "http://i2p" + request;
|
||||
}
|
||||
pos = request.indexOf("//");
|
||||
@ -158,7 +157,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
destination = wwwProxy;
|
||||
usingWWWProxy = true;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
|
||||
_log.debug(getPrefix() + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
|
||||
} else {
|
||||
request = request.substring(pos + 1);
|
||||
pos = request.indexOf("/");
|
||||
@ -168,27 +167,27 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol);
|
||||
if (!isValid) {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info("notValid(" + host + ")");
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "notValid(" + host + ")");
|
||||
method = null;
|
||||
destination = null;
|
||||
break;
|
||||
} else if (!usingWWWProxy) {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info("host=getHostName(" + destination + ")");
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "host=getHostName(" + destination + ")");
|
||||
host = getHostName(destination); // hide original host
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("METHOD:" + method + ":");
|
||||
_log.debug("PROTOC:" + protocol + ":");
|
||||
_log.debug("HOST :" + host + ":");
|
||||
_log.debug("DEST :" + destination + ":");
|
||||
_log.debug(getPrefix() + "METHOD:" + method + ":");
|
||||
_log.debug(getPrefix() + "PROTOC:" + protocol + ":");
|
||||
_log.debug(getPrefix() + "HOST :" + host + ":");
|
||||
_log.debug(getPrefix() + "DEST :" + destination + ":");
|
||||
}
|
||||
|
||||
} else {
|
||||
if (line.startsWith("Host: ") && !usingWWWProxy) {
|
||||
line = "Host: " + host;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Setting host = " + host);
|
||||
_log.info(getPrefix() + "Setting host = " + host);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +199,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("NewRequest header: [" + newRequest.toString() + "]");
|
||||
_log.debug(getPrefix() + "NewRequest header: [" + newRequest.toString() + "]");
|
||||
|
||||
while (br.ready()) { // empty the buffer (POST requests)
|
||||
int i = br.read();
|
||||
@ -222,11 +221,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Destination: " + destination);
|
||||
_log.debug(getPrefix() + "Destination: " + destination);
|
||||
|
||||
Destination dest = I2PTunnel.destFromName(destination);
|
||||
if (dest == null) {
|
||||
l.log("Could not resolve " + destination + ".");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
|
||||
writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, destination);
|
||||
s.close();
|
||||
return;
|
||||
@ -239,19 +240,19 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
timeoutThread.start();
|
||||
} catch (SocketException ex) {
|
||||
if (timeoutThread != null) timeoutThread.disable();
|
||||
_log.info("Error trying to connect", ex);
|
||||
_log.info(getPrefix() + "Error trying to connect", ex);
|
||||
l.log(ex.getMessage());
|
||||
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
|
||||
closeSocket(s);
|
||||
} catch (IOException ex) {
|
||||
if (timeoutThread != null) timeoutThread.disable();
|
||||
_log.info("Error trying to connect", ex);
|
||||
_log.info(getPrefix() + "Error trying to connect", ex);
|
||||
l.log(ex.getMessage());
|
||||
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
|
||||
closeSocket(s);
|
||||
} catch (I2PException ex) {
|
||||
if (timeoutThread != null) timeoutThread.disable();
|
||||
_log.info("Error trying to connect", ex);
|
||||
_log.info("getPrefix() + Error trying to connect", ex);
|
||||
l.log(ex.getMessage());
|
||||
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
|
||||
closeSocket(s);
|
||||
@ -280,7 +281,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
_useWWWProxy = useWWWProxy;
|
||||
_disabled = false;
|
||||
long timeoutId = ++__timeoutId;
|
||||
setName("InactivityThread " + timeoutId);
|
||||
setName("InactivityThread " + getPrefix() + timeoutId);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
@ -293,15 +294,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
public void run() {
|
||||
while (!_disabled) {
|
||||
if (_runner.isFinished()) {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info("HTTP client request completed prior to timeout");
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "HTTP client request completed prior to timeout");
|
||||
return;
|
||||
}
|
||||
if (_runner.getLastActivityOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
|
||||
if (_runner.getStartedOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("HTTP client request timed out (lastActivity: "
|
||||
_log.warn(getPrefix() + "HTTP client request timed out (lastActivity: "
|
||||
+ new Date(_runner.getLastActivityOn()) + ", startedOn: "
|
||||
+ new Date(_runner.getLastActivityOn()) + ")");
|
||||
+ new Date(_runner.getStartedOn()) + ")");
|
||||
timeout();
|
||||
return;
|
||||
} else {
|
||||
@ -320,7 +321,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
|
||||
private void timeout() {
|
||||
_log.info("Inactivity timeout reached");
|
||||
_log.info(getPrefix() + "Inactivity timeout reached");
|
||||
l.log("Inactivity timeout reached");
|
||||
if (_out != null) {
|
||||
try {
|
||||
@ -330,10 +331,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
writeErrorMessage(ERR_TIMEOUT, _out, _targetRequest, _useWWWProxy, wwwProxy);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_log.warn("Error writing out the 'timeout' message", ioe);
|
||||
_log.warn(getPrefix() + "Error writing out the 'timeout' message", ioe);
|
||||
}
|
||||
} else {
|
||||
_log.warn("Client disconnected before we could say we timed out");
|
||||
_log.warn(getPrefix() + "Client disconnected before we could say we timed out");
|
||||
}
|
||||
closeSocket(s);
|
||||
}
|
||||
@ -364,16 +365,19 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
|
||||
private void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
|
||||
boolean usingWWWProxy, String wwwProxy) {
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
|
||||
if (out != null) {
|
||||
try {
|
||||
writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, wwwProxy);
|
||||
} catch (IOException ioe) {
|
||||
_log.warn("Error writing out the 'destination was unknown' " + "message", ioe);
|
||||
_log.warn(getPrefix() + "Error writing out the 'destination was unknown' " + "message", ioe);
|
||||
}
|
||||
} else {
|
||||
_log.warn("Client disconnected before we could say that destination " + "was unknown", ex);
|
||||
_log.warn(getPrefix() + "Client disconnected before we could say that destination " + "was unknown", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2PTunnelRunner extends I2PThread {
|
||||
public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorListener {
|
||||
private final static Log _log = new Log(I2PTunnelRunner.class);
|
||||
|
||||
private static volatile long __runnerId;
|
||||
@ -51,8 +51,9 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
this.slock = slock;
|
||||
this.initialData = initialData;
|
||||
lastActivityOn = -1;
|
||||
startedOn = -1;
|
||||
_log.info("I2PTunnelRunner started");
|
||||
startedOn = Clock.getInstance().now();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("I2PTunnelRunner started");
|
||||
_runnerId = ++__runnerId;
|
||||
setName("I2PTunnelRunner " + _runnerId);
|
||||
start();
|
||||
@ -90,10 +91,10 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
startedOn = Clock.getInstance().now();
|
||||
try {
|
||||
InputStream in = s.getInputStream();
|
||||
OutputStream out = new BufferedOutputStream(s.getOutputStream(), NETWORK_BUFFER_SIZE);
|
||||
i2ps.setSocketErrorListener(this);
|
||||
InputStream i2pin = i2ps.getInputStream();
|
||||
OutputStream i2pout = new BufferedOutputStream(i2ps.getOutputStream(), MAX_PACKET_SIZE);
|
||||
if (initialData != null) {
|
||||
@ -121,6 +122,8 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
_log.debug("Error forwarding", ex);
|
||||
} catch (Exception e) {
|
||||
_log.error("Internal error", e);
|
||||
} finally {
|
||||
try {
|
||||
if (s != null) s.close();
|
||||
@ -132,6 +135,13 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
}
|
||||
}
|
||||
|
||||
public void errorOccurred() {
|
||||
synchronized (finishLock) {
|
||||
finished = true;
|
||||
finishLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
private volatile long __forwarderId = 0;
|
||||
|
||||
private class StreamForwarder extends I2PThread {
|
||||
@ -187,7 +197,8 @@ public class I2PTunnelRunner extends I2PThread {
|
||||
out.close();
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
_log.error("Error closing streams", ex);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error closing streams", ex);
|
||||
}
|
||||
synchronized (finishLock) {
|
||||
finished = true;
|
||||
|
@ -14,6 +14,7 @@ import java.net.SocketException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
@ -44,15 +45,15 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
/** default timeout to 3 minutes - override if desired */
|
||||
private long readTimeout = DEFAULT_READ_TIMEOUT;
|
||||
|
||||
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) {
|
||||
super(host + ":" + port + " <- " + privData, notifyThis);
|
||||
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privData, notifyThis, tunnel);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData));
|
||||
init(host, port, bais, privData, l);
|
||||
}
|
||||
|
||||
public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l,
|
||||
EventDispatcher notifyThis) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis);
|
||||
EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
|
||||
try {
|
||||
init(host, port, new FileInputStream(privkey), privkeyname, l);
|
||||
} catch (IOException ioe) {
|
||||
@ -61,8 +62,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis);
|
||||
public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel);
|
||||
init(host, port, privData, privkeyname, l);
|
||||
}
|
||||
|
||||
@ -72,12 +73,13 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
this.remotePort = port;
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
Properties props = new Properties();
|
||||
props.putAll(System.getProperties());
|
||||
props.putAll(getTunnel().getClientOptions());
|
||||
synchronized (slock) {
|
||||
sockMgr = I2PSocketManagerFactory.createManager(privData, I2PTunnel.host, Integer.parseInt(I2PTunnel.port),
|
||||
props);
|
||||
|
||||
}
|
||||
sockMgr.setName("Server");
|
||||
l.log("Ready!");
|
||||
notifyEvent("openServerResult", "ok");
|
||||
open = true;
|
||||
@ -144,15 +146,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
I2PServerSocket i2pss = sockMgr.getServerSocket();
|
||||
while (true) {
|
||||
I2PSocket i2ps = i2pss.accept();
|
||||
//local is fast, so synchronously. Does not need that many
|
||||
//threads.
|
||||
try {
|
||||
i2ps.setReadTimeout(readTimeout);
|
||||
Socket s = new Socket(remoteHost, remotePort);
|
||||
new I2PTunnelRunner(s, i2ps, slock, null);
|
||||
} catch (SocketException ex) {
|
||||
i2ps.close();
|
||||
}
|
||||
I2PThread t = new I2PThread(new Handler(i2ps));
|
||||
t.start();
|
||||
}
|
||||
} catch (I2PException ex) {
|
||||
_log.error("Error while waiting for I2PConnections", ex);
|
||||
@ -160,5 +155,43 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
_log.error("Error while waiting for I2PConnections", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Async handler to keep .accept() from blocking too long.
|
||||
* todo: replace with a thread pool so we dont get overrun by threads if/when
|
||||
* receiving a lot of connection requests concurrently.
|
||||
*
|
||||
*/
|
||||
private class Handler implements Runnable {
|
||||
private I2PSocket _handleSocket;
|
||||
public Handler(I2PSocket socket) {
|
||||
_handleSocket = socket;
|
||||
}
|
||||
public void run() {
|
||||
long afterAccept = I2PAppContext.getGlobalContext().clock().now();
|
||||
long afterSocket = -1;
|
||||
//local is fast, so synchronously. Does not need that many
|
||||
//threads.
|
||||
try {
|
||||
_handleSocket.setReadTimeout(readTimeout);
|
||||
Socket s = new Socket(remoteHost, remotePort);
|
||||
afterSocket = I2PAppContext.getGlobalContext().clock().now();
|
||||
new I2PTunnelRunner(s, _handleSocket, slock, null);
|
||||
} catch (SocketException ex) {
|
||||
try {
|
||||
_handleSocket.close();
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error while closing the received i2p con", ex);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
_log.error("Error while waiting for I2PConnections", ex);
|
||||
}
|
||||
|
||||
long afterHandle = I2PAppContext.getGlobalContext().clock().now();
|
||||
long timeToHandle = afterHandle - afterAccept;
|
||||
if (timeToHandle > 1000)
|
||||
_log.warn("Took a while to handle the request [" + timeToHandle + ", socket create: " + (afterSocket-afterAccept) + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,16 +26,19 @@ public abstract class I2PTunnelTask implements EventDispatcher {
|
||||
// I2PTunnelTask(name, (EventDispatcher)null);
|
||||
//}
|
||||
|
||||
protected I2PTunnelTask(String name, EventDispatcher notifyThis) {
|
||||
protected I2PTunnelTask(String name, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
attachEventDispatcher(notifyThis);
|
||||
this.name = name;
|
||||
this.id = -1;
|
||||
this.tunnel = tunnel;
|
||||
}
|
||||
|
||||
/** for apps that use multiple I2PTunnel instances */
|
||||
public void setTunnel(I2PTunnel pTunnel) {
|
||||
tunnel = pTunnel;
|
||||
}
|
||||
|
||||
public I2PTunnel getTunnel() { return tunnel; }
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
|
@ -47,15 +47,15 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
|
||||
// I2Ping(cmd, l, (EventDispatcher)null);
|
||||
//}
|
||||
|
||||
public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis) {
|
||||
super("I2Ping [" + cmd + "]", notifyThis);
|
||||
public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super("I2Ping [" + cmd + "]", notifyThis, tunnel);
|
||||
this.l = l;
|
||||
command = cmd;
|
||||
synchronized (slock) {
|
||||
if (ownDest) {
|
||||
sockMgr = I2PTunnelClient.buildSocketManager();
|
||||
sockMgr = I2PTunnelClient.buildSocketManager(tunnel);
|
||||
} else {
|
||||
sockMgr = I2PTunnelClient.getSocketManager();
|
||||
sockMgr = I2PTunnelClient.getSocketManager(tunnel);
|
||||
}
|
||||
}
|
||||
Thread t = new I2PThread(this);
|
||||
|
@ -10,6 +10,7 @@ import java.net.Socket;
|
||||
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.i2ptunnel.I2PTunnel;
|
||||
import net.i2p.i2ptunnel.I2PTunnelClientBase;
|
||||
import net.i2p.i2ptunnel.I2PTunnelRunner;
|
||||
import net.i2p.i2ptunnel.Logging;
|
||||
@ -26,8 +27,8 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
|
||||
// I2PSOCKSTunnel(localPort, l, ownDest, (EventDispatcher)null);
|
||||
//}
|
||||
|
||||
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis) {
|
||||
super(localPort, ownDest, l, notifyThis, "SOCKSHandler");
|
||||
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
|
||||
super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel);
|
||||
|
||||
if (waitEventValue("openBaseClientResult").equals("error")) {
|
||||
notifyEvent("openSOCKSTunnelResult", "error");
|
||||
|
@ -8,7 +8,7 @@
|
||||
<target name="compile">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac srcdir="./src" debug="true" destdir="./build/obj" classpath="../../../core/java/build/i2p.jar" />
|
||||
<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/mstreaming.jar" basedir="./build/obj" includes="**/*.class" />
|
||||
|
@ -1,31 +1,71 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
/** Like a StringBuffer, but for bytes */
|
||||
/**
|
||||
* Like a StringBuffer, but for bytes. This class is not internally synchronized,
|
||||
* so care should be taken when using in a multithreaded environment.
|
||||
*
|
||||
*/
|
||||
public class ByteCollector {
|
||||
byte[] contents;
|
||||
int size;
|
||||
|
||||
private static final int INITIAL_CAPACITY = 1024;
|
||||
private static final int SHORT_CAPACITY = 80;
|
||||
|
||||
/**
|
||||
* New collector with the default initial capacity
|
||||
*
|
||||
*/
|
||||
public ByteCollector() {
|
||||
contents = new byte[80];
|
||||
this(INITIAL_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* New collector with an initial capacity as specified
|
||||
*
|
||||
*/
|
||||
public ByteCollector(int capacity) {
|
||||
contents = new byte[capacity];
|
||||
size = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* New collector containing the specified bytes
|
||||
*
|
||||
*/
|
||||
public ByteCollector(byte[] b) {
|
||||
this();
|
||||
append(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* New collector with the specified byte
|
||||
*
|
||||
*/
|
||||
public ByteCollector(byte b) {
|
||||
this();
|
||||
append(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new byte to the collector (extending the buffer if necessary)
|
||||
*
|
||||
* @param b byte to add
|
||||
* @return this object
|
||||
*/
|
||||
public ByteCollector append(byte b) {
|
||||
ensureCapacity(size + 1);
|
||||
contents[size++] = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new bytes to the collector (extending the buffer if necessary)
|
||||
*
|
||||
* @param b bytes to add
|
||||
* @return this object
|
||||
*/
|
||||
public ByteCollector append(byte[] b) {
|
||||
ensureCapacity(size + b.length);
|
||||
System.arraycopy(b, 0, contents, size, b.length);
|
||||
@ -33,10 +73,25 @@ public class ByteCollector {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new bytes to the collector (extending the buffer if necessary)
|
||||
*
|
||||
* @param b byte array to add from
|
||||
* @param len number of bytes in the array to add
|
||||
* @return this object
|
||||
*/
|
||||
public ByteCollector append(byte[] b, int len) {
|
||||
return append(b, 0, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new bytes to the collector (extending the buffer if necessary)
|
||||
*
|
||||
* @param b byte array to add from
|
||||
* @param off offset into the array to begin adding from
|
||||
* @param len number of bytes in the array to add
|
||||
* @return this object
|
||||
*/
|
||||
public ByteCollector append(byte[] b, int off, int len) {
|
||||
ensureCapacity(size + len);
|
||||
System.arraycopy(b, off, contents, size, len);
|
||||
@ -44,17 +99,36 @@ public class ByteCollector {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the contents of the byte collector to the current collector (extending the buffer if necessary)
|
||||
*
|
||||
* @param bc collector to copy
|
||||
* @return this object
|
||||
*/
|
||||
public ByteCollector append(ByteCollector bc) {
|
||||
// optimieren?
|
||||
return append(bc.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the contents of the collector into a new array and return it
|
||||
*
|
||||
* @return new array containing a copy of the current collector's data
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
byte[] result = new byte[size];
|
||||
System.arraycopy(contents, 0, result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull off the first $maxlen bytes from the collector, shifting the remaining
|
||||
* bytes into the beginning of the collector's array.
|
||||
*
|
||||
* @param maxlen max number of bytes we want to pull from the collector (we will get
|
||||
* less if the collector doesnt have that many bytes yet)
|
||||
* @return copy of the bytes pulled from the collector
|
||||
*/
|
||||
public byte[] startToByteArray(int maxlen) {
|
||||
if (size < maxlen) {
|
||||
byte[] res = toByteArray();
|
||||
@ -69,10 +143,22 @@ public class ByteCollector {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How many bytes are available for retrieval?
|
||||
*
|
||||
* @return number of bytes
|
||||
*/
|
||||
public int getCurrentSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure we have sufficient storage space.
|
||||
*
|
||||
* @param cap minimum number of bytes that the buffer should contain
|
||||
* @return true if the the collector was expanded to meet the minimum,
|
||||
* false if it was already large enough
|
||||
*/
|
||||
public boolean ensureCapacity(int cap) {
|
||||
if (contents.length < cap) {
|
||||
int l = contents.length;
|
||||
@ -87,20 +173,46 @@ public class ByteCollector {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the collector have meaningful data or is it empty?
|
||||
*
|
||||
* @return true if it has no data
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through the collector for the first occurrence of the sequence of
|
||||
* bytes contained within the specified collector
|
||||
*
|
||||
* @param bc bytes that will be searched for
|
||||
* @return index into the current collector, or -1 if it isn't found
|
||||
*/
|
||||
public int indexOf(ByteCollector bc) {
|
||||
// optimieren?
|
||||
return indexOf(bc.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through the collector for the first occurrence of the specified
|
||||
* byte
|
||||
*
|
||||
* @param b byte that will be searched for
|
||||
* @return index into the current collector, or -1 if it isn't found
|
||||
*/
|
||||
public int indexOf(byte b) {
|
||||
// optimieren?
|
||||
return indexOf(new byte[] { b});
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through the collector for the first occurrence of the sequence of
|
||||
* bytes
|
||||
*
|
||||
* @param ba bytes that will be searched for
|
||||
* @return index into the current collector, or -1 if it isn't found
|
||||
*/
|
||||
public int indexOf(byte[] ba) {
|
||||
loop: for (int i = 0; i < size - ba.length + 1; i++) {
|
||||
for (int j = 0; j < ba.length; j++) {
|
||||
@ -111,15 +223,28 @@ public class ByteCollector {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the collector. This does not affect its capacity.
|
||||
*
|
||||
*/
|
||||
public void clear() {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the collector and reduce its capacity.
|
||||
*
|
||||
*/
|
||||
public void clearAndShorten() {
|
||||
size = 0;
|
||||
contents = new byte[80];
|
||||
contents = new byte[SHORT_CAPACITY];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the bytes as a string
|
||||
*
|
||||
* @return the, uh, string
|
||||
*/
|
||||
public String toString() {
|
||||
return new String(toByteArray());
|
||||
}
|
||||
@ -132,6 +257,12 @@ public class ByteCollector {
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the collectors.
|
||||
*
|
||||
* @return true if and only if both are the same size and the
|
||||
* byte arrays they contain are equal.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ByteCollector) {
|
||||
ByteCollector by = (ByteCollector) o;
|
||||
@ -145,7 +276,13 @@ public class ByteCollector {
|
||||
}
|
||||
}
|
||||
|
||||
public byte removeFirst() {
|
||||
/**
|
||||
* Remove the first byte from the collector, shifting its contents accordingly.
|
||||
*
|
||||
* @return byte removed
|
||||
* @throws IllegalArgumentException if the collector is empty
|
||||
*/
|
||||
public byte removeFirst() throws IllegalArgumentException {
|
||||
byte bb = contents[0];
|
||||
if (size == 0) throw new IllegalArgumentException("ByteCollector is empty");
|
||||
if (size > 1)
|
||||
|
@ -1,15 +1,14 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import java.net.ConnectException;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Server socket implementation, allowing multiple threads to accept I2PSockets
|
||||
@ -90,7 +89,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
*/
|
||||
public boolean addWaitForAccept(I2PSocket s, long timeoutMs) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("addWaitForAccept [new socket arrived, pending: " + pendingSockets.size());
|
||||
_log.debug("addWaitForAccept [new socket arrived [" + s.toString() + "], pending: " + pendingSockets.size());
|
||||
|
||||
if (closing) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@ -112,7 +111,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
long now = clock.now();
|
||||
if (now >= end) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Expired while waiting for accept (time elapsed =" + (now - start) + "ms");
|
||||
_log.info("Expired while waiting for accept (time elapsed =" + (now - start) + "ms) for socket " + s.toString());
|
||||
pendingSockets.remove(s);
|
||||
return false;
|
||||
}
|
||||
@ -131,7 +130,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
|
||||
}
|
||||
long now = clock.now();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.info("Socket accepted after " + (now-start) + "ms");
|
||||
_log.info("Socket accepted after " + (now-start) + "ms for socket " + s.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -50,4 +50,21 @@ public interface I2PSocket {
|
||||
* Closes the socket if not closed yet
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
|
||||
public void setSocketErrorListener(SocketErrorListener lsnr);
|
||||
/**
|
||||
* Allow notification of underlying errors communicating across I2P without
|
||||
* waiting for any sort of cleanup process. For example, if some data could
|
||||
* not be sent, this listener is notified immediately, and while the input/output
|
||||
* streams are notified through IOExceptions, they are told only after the
|
||||
* TCP-like stream is closed (which may be a minute later, if the close message
|
||||
* times out as well). This is not fired on normal close() activity.
|
||||
*
|
||||
*/
|
||||
public interface SocketErrorListener {
|
||||
/**
|
||||
* An error occurred communicating with the peer.
|
||||
*/
|
||||
void errorOccurred();
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Initial stub implementation for the socket
|
||||
*
|
||||
@ -29,7 +31,15 @@ class I2PSocketImpl implements I2PSocket {
|
||||
private Object remoteIDWaiter = new Object();
|
||||
private I2PInputStream in;
|
||||
private I2POutputStream out;
|
||||
private SocketErrorListener _socketErrorListener;
|
||||
private boolean outgoing;
|
||||
private long _socketId;
|
||||
private static long __socketId = 0;
|
||||
private long _bytesRead = 0;
|
||||
private long _bytesWritten = 0;
|
||||
private long _createdOn;
|
||||
private long _closedOn;
|
||||
private long _remoteIdSetTime;
|
||||
private Object flagLock = new Object();
|
||||
|
||||
/**
|
||||
@ -61,12 +71,16 @@ class I2PSocketImpl implements I2PSocket {
|
||||
this.outgoing = outgoing;
|
||||
manager = mgr;
|
||||
remote = peer;
|
||||
_socketId = ++__socketId;
|
||||
local = mgr.getSession().getMyDestination();
|
||||
in = new I2PInputStream();
|
||||
I2PInputStream pin = new I2PInputStream();
|
||||
out = new I2POutputStream(pin);
|
||||
new I2PSocketRunner(pin);
|
||||
this.localID = localID;
|
||||
_createdOn = I2PAppContext.getGlobalContext().clock().now();
|
||||
_remoteIdSetTime = -1;
|
||||
_closedOn = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,6 +97,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
public void setRemoteID(String id) {
|
||||
synchronized (remoteIDWaiter) {
|
||||
remoteID = id;
|
||||
_remoteIdSetTime = System.currentTimeMillis();
|
||||
remoteIDWaiter.notifyAll();
|
||||
}
|
||||
}
|
||||
@ -117,16 +132,23 @@ class I2PSocketImpl implements I2PSocket {
|
||||
long dieAfter = System.currentTimeMillis() + maxWait;
|
||||
synchronized (remoteIDWaiter) {
|
||||
if (wait) {
|
||||
try {
|
||||
if (maxWait >= 0)
|
||||
remoteIDWaiter.wait(maxWait);
|
||||
else
|
||||
remoteIDWaiter.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
if (remoteID == null) {
|
||||
try {
|
||||
if (maxWait >= 0)
|
||||
remoteIDWaiter.wait(maxWait);
|
||||
else
|
||||
remoteIDWaiter.wait();
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((maxWait >= 0) && (System.currentTimeMillis() >= dieAfter))
|
||||
throw new InterruptedIOException("Timed out waiting for remote ID");
|
||||
long now = System.currentTimeMillis();
|
||||
if ((maxWait >= 0) && (now >= dieAfter)) {
|
||||
long waitedExcess = now - dieAfter;
|
||||
throw new InterruptedIOException("Timed out waiting for remote ID (waited " + waitedExcess
|
||||
+ "ms too long [" + maxWait + "ms, remId " + remoteID
|
||||
+ ", remId set " + (now-_remoteIdSetTime) + "ms ago])");
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("TIMING: RemoteID set to "
|
||||
@ -153,6 +175,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
* @param data the data to inject into our local inputStream
|
||||
*/
|
||||
public void queueData(byte[] data) {
|
||||
_bytesRead += data.length;
|
||||
in.queueData(data);
|
||||
}
|
||||
|
||||
@ -192,8 +215,10 @@ class I2PSocketImpl implements I2PSocket {
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
synchronized (flagLock) {
|
||||
_log.debug("Closing connection");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closing connection");
|
||||
closed = true;
|
||||
_closedOn = I2PAppContext.getGlobalContext().clock().now();
|
||||
}
|
||||
out.close();
|
||||
in.notifyClosed();
|
||||
@ -207,6 +232,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
closed = true;
|
||||
closed2 = true;
|
||||
sendClose = false;
|
||||
_closedOn = I2PAppContext.getGlobalContext().clock().now();
|
||||
}
|
||||
out.close();
|
||||
in.notifyClosed();
|
||||
@ -232,6 +258,23 @@ class I2PSocketImpl implements I2PSocket {
|
||||
in.setReadTimeout(ms);
|
||||
}
|
||||
|
||||
public void setSocketErrorListener(SocketErrorListener lsnr) {
|
||||
_socketErrorListener = lsnr;
|
||||
}
|
||||
|
||||
void errorOccurred() {
|
||||
if (_socketErrorListener != null)
|
||||
_socketErrorListener.errorOccurred();
|
||||
}
|
||||
|
||||
public long getBytesSent() { return _bytesWritten; }
|
||||
public long getBytesReceived() { return _bytesRead; }
|
||||
public long getCreatedOn() { return _createdOn; }
|
||||
public long getClosedOn() { return _closedOn; }
|
||||
|
||||
|
||||
private String getPrefix() { return "[" + _socketId + "]: "; }
|
||||
|
||||
//--------------------------------------------------
|
||||
private class I2PInputStream extends InputStream {
|
||||
|
||||
@ -255,40 +298,49 @@ class I2PSocketImpl implements I2PSocket {
|
||||
throw new RuntimeException("Incorrect read() result");
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
||||
_log.debug("Read called: " + this.hashCode());
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix() + "Read called for " + len + " bytes (avail=" + bc.getCurrentSize() + "): " + this.hashCode());
|
||||
if (len == 0) return 0;
|
||||
long dieAfter = System.currentTimeMillis() + readTimeout;
|
||||
byte[] read = bc.startToByteArray(len);
|
||||
byte[] read = null;
|
||||
synchronized (bc) {
|
||||
read = bc.startToByteArray(len);
|
||||
}
|
||||
boolean timedOut = false;
|
||||
|
||||
while (read.length == 0) {
|
||||
synchronized (flagLock) {
|
||||
if (closed) {
|
||||
_log.debug("Closed is set, so closing stream: " + hashCode());
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix() + "Closed is set after reading " + _bytesRead + " and writing " + _bytesWritten + ", so closing stream: " + hashCode());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (readTimeout >= 0) {
|
||||
wait(readTimeout);
|
||||
} else {
|
||||
wait();
|
||||
synchronized (I2PSocketImpl.I2PInputStream.this) {
|
||||
if (readTimeout >= 0) {
|
||||
wait(readTimeout);
|
||||
} else {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {}
|
||||
|
||||
if ((readTimeout >= 0)
|
||||
&& (System.currentTimeMillis() >= dieAfter)) {
|
||||
throw new InterruptedIOException("Timeout reading from I2PSocket (" + readTimeout + " msecs)");
|
||||
throw new InterruptedIOException(getPrefix() + "Timeout reading from I2PSocket (" + readTimeout + " msecs)");
|
||||
}
|
||||
|
||||
read = bc.startToByteArray(len);
|
||||
synchronized (bc) {
|
||||
read = bc.startToByteArray(len);
|
||||
}
|
||||
}
|
||||
if (read.length > len) throw new RuntimeException("BUG");
|
||||
System.arraycopy(read, 0, b, off, read.length);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("Read from I2PInputStream " + hashCode() + " returned "
|
||||
_log.debug(getPrefix() + "Read from I2PInputStream " + hashCode() + " returned "
|
||||
+ read.length + " bytes");
|
||||
}
|
||||
//if (_log.shouldLog(Log.DEBUG)) {
|
||||
@ -300,22 +352,30 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return bc.getCurrentSize();
|
||||
synchronized (bc) {
|
||||
return bc.getCurrentSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void queueData(byte[] data) {
|
||||
queueData(data, 0, data.length);
|
||||
}
|
||||
|
||||
public synchronized void queueData(byte[] data, int off, int len) {
|
||||
public void queueData(byte[] data, int off, int len) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Insert " + len + " bytes into queue: " + hashCode());
|
||||
bc.append(data, off, len);
|
||||
notifyAll();
|
||||
_log.debug(getPrefix() + "Insert " + len + " bytes into queue: " + hashCode());
|
||||
synchronized (bc) {
|
||||
bc.append(data, off, len);
|
||||
}
|
||||
synchronized (I2PInputStream.this) {
|
||||
I2PInputStream.this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void notifyClosed() {
|
||||
I2PInputStream.this.notifyAll();
|
||||
public void notifyClosed() {
|
||||
synchronized (I2PInputStream.this) {
|
||||
I2PInputStream.this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
@ -338,6 +398,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
_bytesWritten += len;
|
||||
sendTo.queueData(b, off, len);
|
||||
}
|
||||
|
||||
@ -353,10 +414,10 @@ class I2PSocketImpl implements I2PSocket {
|
||||
|
||||
public I2PSocketRunner(InputStream in) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Runner's input stream is: " + in.hashCode());
|
||||
_log.debug(getPrefix() + "Runner's input stream is: " + in.hashCode());
|
||||
this.in = in;
|
||||
String peer = I2PSocketImpl.this.remote.calculateHash().toBase64();
|
||||
setName("SocketRunner " + (++__runnerId) + " " + peer.substring(0, 4));
|
||||
setName("SocketRunner " + (++__runnerId) + "/" + _socketId + " " + peer.substring(0, 4));
|
||||
start();
|
||||
}
|
||||
|
||||
@ -378,7 +439,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
if ((bcsize < MAX_PACKET_SIZE) && (in.available() == 0)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Runner Point d: " + hashCode());
|
||||
_log.debug(getPrefix() + "Runner Point d: " + hashCode());
|
||||
|
||||
try {
|
||||
Thread.sleep(PACKET_DELAY);
|
||||
@ -390,10 +451,12 @@ class I2PSocketImpl implements I2PSocket {
|
||||
byte[] data = bc.startToByteArray(MAX_PACKET_SIZE);
|
||||
if (data.length > 0) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Message size is: " + data.length);
|
||||
_log.debug(getPrefix() + "Message size is: " + data.length);
|
||||
boolean sent = sendBlock(data);
|
||||
if (!sent) {
|
||||
_log.error("Error sending message to peer. Killing socket runner");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix() + "Error sending message to peer. Killing socket runner");
|
||||
errorOccurred();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -413,9 +476,10 @@ class I2PSocketImpl implements I2PSocket {
|
||||
packetsHandled++;
|
||||
}
|
||||
if ((bc.getCurrentSize() > 0) && (packetsHandled > 1)) {
|
||||
_log.error("A SCARY MONSTER HAS EATEN SOME DATA! " + "(input stream: "
|
||||
+ in.hashCode() + "; "
|
||||
+ "queue size: " + bc.getCurrentSize() + ")");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix() + "We lost some data queued up due to a network send error (input stream: "
|
||||
+ in.hashCode() + "; "
|
||||
+ "queue size: " + bc.getCurrentSize() + ")");
|
||||
}
|
||||
synchronized (flagLock) {
|
||||
closed2 = true;
|
||||
@ -426,32 +490,34 @@ class I2PSocketImpl implements I2PSocket {
|
||||
} // FIXME: Race here?
|
||||
if (sc) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Sending close packet: " + outgoing);
|
||||
_log.info(getPrefix() + "Sending close packet: (we started? " + outgoing + ") after reading " + _bytesRead + " and writing " + _bytesWritten);
|
||||
byte[] packet = I2PSocketManager.makePacket(getMask(0x02), remoteID, new byte[0]);
|
||||
boolean sent = manager.getSession().sendMessage(remote, packet);
|
||||
if (!sent) {
|
||||
_log.error("Error sending close packet to peer");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix() + "Error sending close packet to peer");
|
||||
errorOccurred();
|
||||
}
|
||||
}
|
||||
manager.removeSocket(I2PSocketImpl.this);
|
||||
} catch (InterruptedIOException ex) {
|
||||
_log.error("BUG! read() operations should not timeout!", ex);
|
||||
_log.error(getPrefix() + "BUG! read() operations should not timeout!", ex);
|
||||
} catch (IOException ex) {
|
||||
// WHOEVER removes this event on inconsistent
|
||||
// state before fixing the inconsistent state (a
|
||||
// reference on the socket in the socket manager
|
||||
// etc.) will get hanged by me personally -- mihi
|
||||
_log.error("Error running - **INCONSISTENT STATE!!!**", ex);
|
||||
_log.error(getPrefix() + "Error running - **INCONSISTENT STATE!!!**", ex);
|
||||
} catch (I2PException ex) {
|
||||
_log.error("Error running - **INCONSISTENT STATE!!!**", ex);
|
||||
_log.error(getPrefix() + "Error running - **INCONSISTENT STATE!!!**", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean sendBlock(byte data[]) throws I2PSessionException {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("TIMING: Block to send for " + I2PSocketImpl.this.hashCode());
|
||||
_log.debug(getPrefix() + "TIMING: Block to send for " + I2PSocketImpl.this.hashCode());
|
||||
if (remoteID == null) {
|
||||
_log.error("NULL REMOTEID");
|
||||
_log.error(getPrefix() + "NULL REMOTEID");
|
||||
return false;
|
||||
}
|
||||
byte[] packet = I2PSocketManager.makePacket(getMask(0x00), remoteID, data);
|
||||
@ -463,4 +529,6 @@ class I2PSocketImpl implements I2PSocket {
|
||||
return sent;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() { return "" + hashCode(); }
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
@ -16,15 +15,17 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.I2PSessionListener;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Centralize the coordination and multiplexing of the local client's streaming.
|
||||
* There should be one I2PSocketManager for each I2PSession, and if an application
|
||||
@ -34,7 +35,8 @@ import net.i2p.util.Log;
|
||||
*
|
||||
*/
|
||||
public class I2PSocketManager implements I2PSessionListener {
|
||||
private final static Log _log = new Log(I2PSocketManager.class);
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private I2PSession _session;
|
||||
private I2PServerSocketImpl _serverSocket = null;
|
||||
private Object lock = new Object(); // for locking socket lists
|
||||
@ -42,6 +44,8 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
private HashMap _inSockets;
|
||||
private I2PSocketOptions _defaultOptions;
|
||||
private long _acceptTimeout;
|
||||
private String _name;
|
||||
private static int __managerId = 0;
|
||||
|
||||
public static final short ACK = 0x51;
|
||||
public static final short CLOSE_OUT = 0x52;
|
||||
@ -58,10 +62,24 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
private static final long ACCEPT_TIMEOUT_DEFAULT = 5*1000;
|
||||
|
||||
public I2PSocketManager() {
|
||||
this("SocketManager " + (++__managerId));
|
||||
}
|
||||
public I2PSocketManager(String name) {
|
||||
_name = name;
|
||||
_session = null;
|
||||
_inSockets = new HashMap(16);
|
||||
_outSockets = new HashMap(16);
|
||||
_acceptTimeout = ACCEPT_TIMEOUT_DEFAULT;
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
_log = _context.logManager().getLog(I2PSocketManager.class);
|
||||
_context.statManager().createRateStat("streaming.lifetime", "How long before the socket is closed?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.sent", "How many bytes are sent in the stream?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.received", "How many bytes are received in the stream?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.transferBalance", "How many streams send more than they receive (positive means more sent, negative means more received)?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.synNoAck", "How many times have we sent a SYN but not received an ACK?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.ackSendFailed", "How many times have we tried to send an ACK to a SYN and failed?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.nackSent", "How many times have we refused a SYN with a NACK?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
_context.statManager().createRateStat("streaming.nackReceived", "How many times have we received a NACK to our SYN?", "streaming", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
|
||||
}
|
||||
|
||||
public I2PSession getSession() {
|
||||
@ -83,12 +101,12 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
public long getAcceptTimeout() { return _acceptTimeout; }
|
||||
|
||||
public void disconnected(I2PSession session) {
|
||||
_log.info("Disconnected from the session");
|
||||
_log.info(getName() + ": Disconnected from the session");
|
||||
destroySocketManager();
|
||||
}
|
||||
|
||||
public void errorOccurred(I2PSession session, String message, Throwable error) {
|
||||
_log.error("Error occurred: [" + message + "]", error);
|
||||
_log.error(getName() + ": Error occurred: [" + message + "]", error);
|
||||
}
|
||||
|
||||
public void messageAvailable(I2PSession session, int msgId, long size) {
|
||||
@ -96,11 +114,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
I2PSocketImpl s;
|
||||
byte msg[] = session.receiveMessage(msgId);
|
||||
if (msg.length == 1 && msg[0] == -1) {
|
||||
_log.debug("Ping received");
|
||||
_log.debug(getName() + ": Ping received");
|
||||
return;
|
||||
}
|
||||
if (msg.length < 4) {
|
||||
_log.error("==== packet too short ====");
|
||||
_log.error(getName() + ": ==== packet too short ====");
|
||||
return;
|
||||
}
|
||||
int type = msg[0] & 0xff;
|
||||
@ -108,7 +126,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
byte[] payload = new byte[msg.length - 4];
|
||||
System.arraycopy(msg, 4, payload, 0, payload.length);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Message read: type = [" + Integer.toHexString(type)
|
||||
_log.debug(getName() + ": Message read: type = [" + Integer.toHexString(type)
|
||||
+ "] id = [" + getReadableForm(id)
|
||||
+ "] payload length: [" + payload.length + "]");
|
||||
switch (type) {
|
||||
@ -137,9 +155,9 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
return;
|
||||
}
|
||||
} catch (I2PException ise) {
|
||||
_log.error("Error processing", ise);
|
||||
_log.error(getName() + ": Error processing", ise);
|
||||
} catch (IllegalStateException ise) {
|
||||
_log.debug("Error processing", ise);
|
||||
_log.debug(getName() + ": Error processing", ise);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,30 +169,45 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
*
|
||||
*/
|
||||
private void ackAvailable(String id, byte payload[]) {
|
||||
long begin = _context.clock().now();
|
||||
I2PSocketImpl s = null;
|
||||
synchronized (lock) {
|
||||
s = (I2PSocketImpl) _outSockets.get(id);
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
_log.warn("No socket responsible for ACK packet");
|
||||
_log.warn(getName() + ": No socket responsible for ACK packet");
|
||||
return;
|
||||
}
|
||||
|
||||
long socketRetrieved = _context.clock().now();
|
||||
|
||||
String remoteId = null;
|
||||
remoteId = s.getRemoteID(false);
|
||||
|
||||
if ( (payload.length == 3) && (remoteId == null) ) {
|
||||
String newID = toString(payload);
|
||||
long beforeSetRemId = _context.clock().now();
|
||||
s.setRemoteID(newID);
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug(getName() + ": ackAvailable - socket retrieval took "
|
||||
+ (socketRetrieved-begin) + "ms, getRemoteId took "
|
||||
+ (beforeSetRemId-socketRetrieved) + "ms, setRemoteId took "
|
||||
+ (_context.clock().now()-beforeSetRemId) + "ms");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// (payload.length != 3 || getRemoteId != null)
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
if (payload.length != 3)
|
||||
_log.warn("Ack packet had " + payload.length + " bytes");
|
||||
_log.warn(getName() + ": Ack packet had " + payload.length + " bytes");
|
||||
else
|
||||
_log.warn("Remote ID already exists? " + remoteId);
|
||||
_log.warn(getName() + ": Remote ID already exists? " + remoteId);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug(getName() + ": invalid ack - socket retrieval took "
|
||||
+ (socketRetrieved-begin) + "ms, overall took "
|
||||
+ (_context.clock().now()-begin) + "ms");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -190,11 +223,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s = (I2PSocketImpl) _outSockets.get(id);
|
||||
}
|
||||
|
||||
_log.debug("*Disconnect outgoing!");
|
||||
_log.debug(getName() + ": *Disconnect outgoing for socket " + s);
|
||||
try {
|
||||
if (s != null) {
|
||||
if (payload.length > 0) {
|
||||
_log.debug("Disconnect packet had "
|
||||
_log.debug(getName() + ": Disconnect packet had "
|
||||
+ payload.length + " bytes");
|
||||
}
|
||||
if (s.getRemoteID(false) == null) {
|
||||
@ -208,7 +241,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
return;
|
||||
} catch (Exception t) {
|
||||
_log.error("Ignoring error on disconnect", t);
|
||||
_log.error(getName() + ": Ignoring error on disconnect for socket " + s, t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,12 +259,13 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
|
||||
// packet send outgoing
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("*Packet send outgoing [" + payload.length + "]");
|
||||
_log.debug(getName() + ": *Packet send outgoing [" + payload.length + "] for socket " + s);
|
||||
if (s != null) {
|
||||
s.queueData(payload);
|
||||
return;
|
||||
} else {
|
||||
_log.error("Null socket with data available");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getName() + ": Null socket with data available");
|
||||
throw new IllegalStateException("Null socket with data available");
|
||||
}
|
||||
}
|
||||
@ -246,7 +280,6 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
*/
|
||||
private void synIncomingAvailable(String id, byte payload[], I2PSession session)
|
||||
throws DataFormatException, I2PSessionException {
|
||||
_log.debug("*Syn!");
|
||||
Destination d = new Destination();
|
||||
d.fromByteArray(payload);
|
||||
|
||||
@ -260,6 +293,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s.setRemoteID(id);
|
||||
}
|
||||
}
|
||||
_log.debug(getName() + ": *Syn! for socket " + s);
|
||||
|
||||
if (!acceptConnections) {
|
||||
// The app did not instantiate an I2PServerSocket
|
||||
@ -269,10 +303,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
replySentOk = _session.sendMessage(d, packet);
|
||||
}
|
||||
if (!replySentOk) {
|
||||
_log.error("Error sending close to " + d.calculateHash().toBase64()
|
||||
_log.error(getName() + ": Error sending close to " + d.calculateHash().toBase64()
|
||||
+ " in response to a new con message",
|
||||
new Exception("Failed creation"));
|
||||
}
|
||||
_context.statManager().addRateData("streaming.nackSent", 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -283,10 +318,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
replySentOk = _session.sendMessage(d, packet);
|
||||
if (!replySentOk) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error sending reply to " + d.calculateHash().toBase64()
|
||||
+ " in response to a new con message",
|
||||
_log.warn(getName() + ": Error sending reply to " + d.calculateHash().toBase64()
|
||||
+ " in response to a new con message for socket " + s,
|
||||
new Exception("Failed creation"));
|
||||
s.internalClose();
|
||||
_context.statManager().addRateData("streaming.ackSendFailed", 1, 1);
|
||||
}
|
||||
} else {
|
||||
// timed out or serverSocket closed
|
||||
@ -294,9 +330,10 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
packet[0] = CLOSE_OUT;
|
||||
boolean nackSent = session.sendMessage(d, packet);
|
||||
if (!nackSent) {
|
||||
_log.warn("Error sending NACK for session creation");
|
||||
_log.warn(getName() + ": Error sending NACK for session creation for socket " + s);
|
||||
}
|
||||
s.internalClose();
|
||||
_context.statManager().addRateData("streaming,nackSent", 1, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -307,7 +344,6 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
*
|
||||
*/
|
||||
private void disconnectIncoming(String id, byte payload[]) {
|
||||
_log.debug("*Disconnect incoming!");
|
||||
I2PSocketImpl s = null;
|
||||
synchronized (lock) {
|
||||
s = (I2PSocketImpl) _inSockets.get(id);
|
||||
@ -316,19 +352,21 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
}
|
||||
|
||||
_log.debug(getName() + ": *Disconnect incoming for socket " + s);
|
||||
|
||||
try {
|
||||
if (payload.length == 0 && s != null) {
|
||||
s.internalClose();
|
||||
return;
|
||||
} else {
|
||||
if ( (payload.length > 0) && (_log.shouldLog(Log.ERROR)) )
|
||||
_log.error("Disconnect packet had " + payload.length + " bytes");
|
||||
_log.error(getName() + ": Disconnect packet had " + payload.length + " bytes");
|
||||
if (s != null)
|
||||
s.internalClose();
|
||||
return;
|
||||
}
|
||||
} catch (Exception t) {
|
||||
_log.error("Ignoring error on disconnect", t);
|
||||
_log.error(getName() + ": Ignoring error on disconnect", t);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -340,18 +378,19 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
* @throws IllegalStateException if the socket isn't open or isn't known
|
||||
*/
|
||||
private void sendIncoming(String id, byte payload[]) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("*Packet send incoming [" + payload.length + "]");
|
||||
I2PSocketImpl s = null;
|
||||
synchronized (lock) {
|
||||
s = (I2PSocketImpl) _inSockets.get(id);
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getName() + ": *Packet send incoming [" + payload.length + "] for socket " + s);
|
||||
|
||||
if (s != null) {
|
||||
s.queueData(payload);
|
||||
return;
|
||||
} else {
|
||||
_log.info("Null socket with data available");
|
||||
_log.info(getName() + ": Null socket with data available");
|
||||
throw new IllegalStateException("Null socket with data available");
|
||||
}
|
||||
}
|
||||
@ -361,7 +400,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
*
|
||||
*/
|
||||
private void handleUnknown(int type, String id, byte payload[]) {
|
||||
_log.error("\n\n=============== Unknown packet! " + "============"
|
||||
_log.error(getName() + ": \n\n=============== Unknown packet! " + "============"
|
||||
+ "\nType: " + (int) type
|
||||
+ "\nID: " + getReadableForm(id)
|
||||
+ "\nBase64'ed Data: " + Base64.encode(payload)
|
||||
@ -375,7 +414,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
|
||||
public void reportAbuse(I2PSession session, int severity) {
|
||||
_log.error("Abuse reported [" + severity + "]");
|
||||
_log.error(getName() + ": Abuse reported [" + severity + "]");
|
||||
}
|
||||
|
||||
public void setDefaultOptions(I2PSocketOptions options) {
|
||||
@ -423,31 +462,37 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
boolean sent = false;
|
||||
sent = _session.sendMessage(peer, packet);
|
||||
if (!sent) {
|
||||
_log.info("Unable to send & receive ack for SYN packet");
|
||||
_log.info(getName() + ": Unable to send & receive ack for SYN packet for socket " + s);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
|
||||
throw new I2PException("Error sending through I2P network");
|
||||
}
|
||||
remoteID = s.getRemoteID(true, options.getConnectTimeout());
|
||||
|
||||
if (remoteID == null)
|
||||
throw new ConnectException("Connection refused by peer");
|
||||
if ("".equals(remoteID))
|
||||
throw new NoRouteToHostException("Unable to reach peer");
|
||||
if (remoteID == null) {
|
||||
_context.statManager().addRateData("streaming.nackReceived", 1, 1);
|
||||
throw new ConnectException("Connection refused by peer for socket " + s);
|
||||
}
|
||||
if ("".equals(remoteID)) {
|
||||
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
|
||||
throw new NoRouteToHostException("Unable to reach peer for socket " + s);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("TIMING: s given out for remoteID "
|
||||
+ getReadableForm(remoteID));
|
||||
_log.debug(getName() + ": TIMING: s given out for remoteID "
|
||||
+ getReadableForm(remoteID) + " for socket " + s);
|
||||
|
||||
return s;
|
||||
} catch (InterruptedIOException ioe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Timeout waiting for ack from syn for id "
|
||||
+ getReadableForm(lcID), ioe);
|
||||
_log.error(getName() + ": Timeout waiting for ack from syn for id "
|
||||
+ getReadableForm(lcID) + " for socket " + s, ioe);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
s.internalClose();
|
||||
_context.statManager().addRateData("streaming.synNoAck", 1, 1);
|
||||
throw new InterruptedIOException("Timeout waiting for ack");
|
||||
} catch (ConnectException ex) {
|
||||
s.internalClose();
|
||||
@ -457,7 +502,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
throw ex;
|
||||
} catch (IOException ex) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error sending syn on id " + getReadableForm(lcID), ex);
|
||||
_log.error(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@ -465,7 +510,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
throw new I2PException("Unhandled IOException occurred");
|
||||
} catch (I2PException ex) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Error sending syn on id " + getReadableForm(lcID), ex);
|
||||
_log.info(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@ -473,7 +518,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
throw ex;
|
||||
} catch (Exception e) {
|
||||
s.internalClose();
|
||||
_log.error("Unhandled error connecting", e);
|
||||
_log.error(getName() + ": Unhandled error connecting", e);
|
||||
throw new ConnectException("Unhandled error connecting: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -514,7 +559,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
id = (String)iter.next();
|
||||
sock = (I2PSocketImpl)_inSockets.get(id);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closing inSocket \""
|
||||
_log.debug(getName() + ": Closing inSocket \""
|
||||
+ getReadableForm(sock.getLocalID()) + "\"");
|
||||
sock.internalClose();
|
||||
}
|
||||
@ -524,13 +569,13 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
id = (String)iter.next();
|
||||
sock = (I2PSocketImpl)_outSockets.get(id);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closing outSocket \""
|
||||
_log.debug(getName() + ": Closing outSocket \""
|
||||
+ getReadableForm(sock.getLocalID()) + "\"");
|
||||
sock.internalClose();
|
||||
}
|
||||
}
|
||||
|
||||
_log.debug("Waiting for all open sockets to really close...");
|
||||
_log.debug(getName() + ": Waiting for all open sockets to really close...");
|
||||
synchronized (lock) {
|
||||
while ((_inSockets.size() != 0) || (_outSockets.size() != 0)) {
|
||||
try {
|
||||
@ -540,11 +585,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
|
||||
try {
|
||||
_log.debug("Destroying I2P session...");
|
||||
_log.debug(getName() + ": Destroying I2P session...");
|
||||
_session.destroySession();
|
||||
_log.debug("I2P session destroyed");
|
||||
_log.debug(getName() + ": I2P session destroyed");
|
||||
} catch (I2PSessionException e) {
|
||||
_log.error("Error destroying I2P session", e);
|
||||
_log.error(getName() + ": Error destroying I2P session", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,21 +615,47 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
try {
|
||||
return _session.sendMessage(peer, new byte[] { (byte) CHAFF});
|
||||
} catch (I2PException ex) {
|
||||
_log.error("I2PException:", ex);
|
||||
_log.error(getName() + ": I2PException:", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSocket(I2PSocketImpl sock) {
|
||||
synchronized (lock) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Removing socket \"" + getReadableForm(sock.getLocalID()) + "\"");
|
||||
_inSockets.remove(sock.getLocalID());
|
||||
_outSockets.remove(sock.getLocalID());
|
||||
lock.notify();
|
||||
}
|
||||
|
||||
long now = _context.clock().now();
|
||||
long lifetime = now - sock.getCreatedOn();
|
||||
long timeSinceClose = now - sock.getClosedOn();
|
||||
long sent = sock.getBytesSent();
|
||||
long recv = sock.getBytesReceived();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug(getName() + ": Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock
|
||||
+ ", send: " + sent + ", recv: " + recv
|
||||
+ ", lifetime: " + lifetime + "ms, time since close: " + timeSinceClose + ")]",
|
||||
new Exception("removeSocket called"));
|
||||
}
|
||||
|
||||
_context.statManager().addRateData("streaming.lifetime", lifetime, lifetime);
|
||||
_context.statManager().addRateData("streaming.sent", sent, lifetime);
|
||||
_context.statManager().addRateData("streaming.received", recv, lifetime);
|
||||
|
||||
if (sent > recv) {
|
||||
_context.statManager().addRateData("streaming.transferBalance", 1, lifetime);
|
||||
} else if (recv > sent) {
|
||||
_context.statManager().addRateData("streaming.transferBalance", -1, lifetime);
|
||||
} else {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() { return _name; }
|
||||
public void setName(String name) { _name = name; }
|
||||
|
||||
public static String getReadableForm(String id) {
|
||||
if (id == null) return "(null)";
|
||||
if (id.length() != 3) return "Bogus";
|
||||
|
@ -0,0 +1,18 @@
|
||||
<html><body>
|
||||
<p>Implements a TCP-like (reliable, authenticated, in order) set of sockets for
|
||||
communicating over the IP-like (unreliable, unauthenticated, unordered) I2P
|
||||
messages.</p>
|
||||
|
||||
<p>When an application wants to use streams, it must fetch an {@link
|
||||
net.i2p.client.streaming.I2PSocketManager} from the {@link
|
||||
net.i2p.client.streaming.I2PSocketManagerFactory}, which in turn builds its own
|
||||
{@link net.i2p.client.I2PSession} internally. All communication over that
|
||||
{@link net.i2p.client.I2PSession} is handled by the {@link
|
||||
net.i2p.client.streaming.I2PSocketManager}, as it imposes its own formatting on
|
||||
the raw messages sent and received. If an application wants to receive streams
|
||||
from other clients on the network, it should access the blocking {@link
|
||||
net.i2p.client.streaming.I2PServerSocket#accept} method, which will provide an
|
||||
{@link net.i2p.client.streaming.I2PSocket} when a new one is available. If an
|
||||
application wants to create a new stream to a peer, it should do so with the
|
||||
appropriate {@link net.i2p.client.streaming.I2PSocketManager#connect} call.</p>
|
||||
</body></html>
|
@ -9,13 +9,13 @@
|
||||
<target name="compile">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac srcdir="./src" debug="true" destdir="./build/obj" includes="net/**/*.java" excludes="net/i2p/netmonitor/gui/**" classpath="../../../core/java/build/i2p.jar" />
|
||||
<javac srcdir="./src" debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj" includes="net/**/*.java" excludes="net/i2p/netmonitor/gui/**" classpath="../../../core/java/build/i2p.jar" />
|
||||
</target>
|
||||
|
||||
<target name="compileGUI" depends="builddep">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac debug="true" destdir="./build/obj">
|
||||
<javac debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj">
|
||||
<src path="src/" />
|
||||
<classpath path="../../../core/java/build/i2p.jar" />
|
||||
<classpath path="../../jfreechart/jfreechart-0.9.17/lib/jcommon-0.9.2.jar" />
|
||||
|
@ -1,17 +1,18 @@
|
||||
package net.i2p.netmonitor;
|
||||
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
import java.util.Properties;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Locale;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Pull out important data from the published routerInfo and stash it away
|
||||
|
@ -1,24 +1,24 @@
|
||||
package net.i2p.netmonitor;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.I2PThread;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.File;
|
||||
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.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Main driver for the app that harvests data about the performance of the network,
|
||||
* building summaries for each peer that change over time. <p />
|
||||
*
|
||||
* Usage: <code>NetMonitor [configFilename]</code> <p />
|
||||
* Usage: <code>NetMonitor [configFilename] [--routers filename[,filename]*]</code> <p />
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -41,15 +41,20 @@ public class NetMonitor {
|
||||
private int _exportDelay;
|
||||
private String _exportDir;
|
||||
private String _netDbDir;
|
||||
private String _explicitRouters;
|
||||
private int _summaryDurationHours;
|
||||
private boolean _isRunning;
|
||||
private Map _peerSummaries;
|
||||
|
||||
public NetMonitor() {
|
||||
this(CONFIG_LOCATION_DEFAULT);
|
||||
this(CONFIG_LOCATION_DEFAULT, null);
|
||||
}
|
||||
public NetMonitor(String configLocation) {
|
||||
this(configLocation, null);
|
||||
}
|
||||
public NetMonitor(String configLocation, String explicitFilenames) {
|
||||
_configLocation = configLocation;
|
||||
_explicitRouters = explicitFilenames;
|
||||
_peerSummaries = new HashMap(32);
|
||||
loadConfig();
|
||||
}
|
||||
@ -120,6 +125,8 @@ public class NetMonitor {
|
||||
public int getSummaryDurationHours() { return _summaryDurationHours; }
|
||||
/** where should we read the data from? */
|
||||
public String getNetDbDir() { return _netDbDir; }
|
||||
/** if specified, contains a set of filenames we want to harvest routerInfo data from */
|
||||
public String getExplicitRouters() { return _explicitRouters; }
|
||||
/**
|
||||
* what peers are we keeping track of?
|
||||
*
|
||||
@ -203,10 +210,30 @@ public class NetMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* main driver for the netMonitor. the usage is:
|
||||
* <code>NetMonitor [configFilename] [--routers filename[,filename]*]</code>
|
||||
*/
|
||||
public static final void main(String args[]) {
|
||||
if (args.length == 1)
|
||||
new NetMonitor(args[0]).startMonitor();
|
||||
else
|
||||
new NetMonitor(CONFIG_LOCATION_DEFAULT).startMonitor();
|
||||
String cfgLocation = CONFIG_LOCATION_DEFAULT;
|
||||
String explicitFilenames = null;
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
cfgLocation = args[0];
|
||||
break;
|
||||
case 2:
|
||||
explicitFilenames = args[1];
|
||||
break;
|
||||
case 3:
|
||||
cfgLocation = args[0];
|
||||
explicitFilenames = args[2];
|
||||
break;
|
||||
default:
|
||||
System.err.println("Usage: NetMonitor [configFilename] [--routers filename[,filename]*]");
|
||||
return;
|
||||
}
|
||||
new NetMonitor(cfgLocation, explicitFilenames).startMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
package net.i2p.netmonitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Active process that drives the monitoring by periodically rading the
|
||||
@ -130,12 +129,35 @@ class NetMonitorRunner implements Runnable {
|
||||
* @return list of File objects pointing at the routers around
|
||||
*/
|
||||
private File[] listRouters() {
|
||||
File dbDir = new File(_monitor.getNetDbDir());
|
||||
File files[] = dbDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File f, String name) {
|
||||
return name.startsWith("routerInfo-");
|
||||
}
|
||||
});
|
||||
if (_monitor.getExplicitRouters() != null) {
|
||||
return listRoutersExplicit();
|
||||
} else {
|
||||
File dbDir = new File(_monitor.getNetDbDir());
|
||||
File files[] = dbDir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File f, String name) {
|
||||
return name.startsWith("routerInfo-");
|
||||
}
|
||||
});
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of router files that were explicitly specified by the netMonitor
|
||||
*
|
||||
*/
|
||||
private File[] listRoutersExplicit() {
|
||||
StringTokenizer tok = new StringTokenizer(_monitor.getExplicitRouters().trim(), ",");
|
||||
List rv = new ArrayList();
|
||||
while (tok.hasMoreTokens()) {
|
||||
String name = tok.nextToken();
|
||||
File cur = new File(name);
|
||||
if (cur.exists())
|
||||
rv.add(cur);
|
||||
}
|
||||
File files[] = new File[rv.size()];
|
||||
for (int i = 0; i < rv.size(); i++)
|
||||
files[i] = (File)rv.get(i);
|
||||
return files;
|
||||
}
|
||||
|
||||
@ -148,4 +170,4 @@ class NetMonitorRunner implements Runnable {
|
||||
Thread.sleep(_monitor.getHarvestDelay());
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package net.i2p.netmonitor;
|
||||
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
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.TreeMap;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* coordinate the data points summarizing the performance of a particular peer
|
||||
|
@ -1,20 +1,17 @@
|
||||
package net.i2p.netmonitor;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Set;
|
||||
import java.util.Locale;
|
||||
import java.util.Date;
|
||||
import java.util.StringTokenizer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Load up the peer summary
|
||||
@ -33,57 +30,61 @@ class PeerSummaryReader {
|
||||
PeerSummary summary = null;
|
||||
String curDescription = null;
|
||||
List curArgs = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("peer\t")) {
|
||||
String name = line.substring("peer\t".length()).trim();
|
||||
summary = monitor.getSummary(name);
|
||||
if (summary == null)
|
||||
summary = new PeerSummary(name);
|
||||
} else if (line.startsWith("## ")) {
|
||||
curDescription = line.substring("## ".length()).trim();
|
||||
curArgs = new ArrayList(4);
|
||||
} else if (line.startsWith("# param ")) {
|
||||
int start = line.indexOf(':');
|
||||
String arg = line.substring(start+1).trim();
|
||||
curArgs.add(arg);
|
||||
} else {
|
||||
StringTokenizer tok = new StringTokenizer(line);
|
||||
String name = tok.nextToken();
|
||||
try {
|
||||
long when = getTime(tok.nextToken());
|
||||
boolean isDouble = false;
|
||||
List argVals = new ArrayList(curArgs.size());
|
||||
while (tok.hasMoreTokens()) {
|
||||
String val = (String)tok.nextToken();
|
||||
if (val.indexOf('.') >= 0) {
|
||||
argVals.add(new Double(val));
|
||||
isDouble = true;
|
||||
} else {
|
||||
argVals.add(new Long(val));
|
||||
try {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("peer\t")) {
|
||||
String name = line.substring("peer\t".length()).trim();
|
||||
summary = monitor.getSummary(name);
|
||||
if (summary == null)
|
||||
summary = new PeerSummary(name);
|
||||
} else if (line.startsWith("## ")) {
|
||||
curDescription = line.substring("## ".length()).trim();
|
||||
curArgs = new ArrayList(4);
|
||||
} else if (line.startsWith("# param ")) {
|
||||
int start = line.indexOf(':');
|
||||
String arg = line.substring(start+1).trim();
|
||||
curArgs.add(arg);
|
||||
} else {
|
||||
StringTokenizer tok = new StringTokenizer(line);
|
||||
String name = tok.nextToken();
|
||||
try {
|
||||
long when = getTime(tok.nextToken());
|
||||
boolean isDouble = false;
|
||||
List argVals = new ArrayList(curArgs.size());
|
||||
while (tok.hasMoreTokens()) {
|
||||
String val = (String)tok.nextToken();
|
||||
if (val.indexOf('.') >= 0) {
|
||||
argVals.add(new Double(val));
|
||||
isDouble = true;
|
||||
} else {
|
||||
argVals.add(new Long(val));
|
||||
}
|
||||
}
|
||||
String valDescriptions[] = new String[curArgs.size()];
|
||||
for (int i = 0; i < curArgs.size(); i++)
|
||||
valDescriptions[i] = (String)curArgs.get(i);
|
||||
if (isDouble) {
|
||||
double values[] = new double[argVals.size()];
|
||||
for (int i = 0; i < argVals.size(); i++)
|
||||
values[i] = ((Double)argVals.get(i)).doubleValue();
|
||||
summary.addData(name, curDescription, valDescriptions, when, values);
|
||||
} else {
|
||||
long values[] = new long[argVals.size()];
|
||||
for (int i = 0; i < argVals.size(); i++)
|
||||
values[i] = ((Long)argVals.get(i)).longValue();
|
||||
summary.addData(name, curDescription, valDescriptions, when, values);
|
||||
}
|
||||
} catch (ParseException pe) {
|
||||
_log.error("Error parsing the data line [" + line + "]", pe);
|
||||
} catch (NumberFormatException nfe) {
|
||||
_log.error("Error parsing the data line [" + line + "]", nfe);
|
||||
}
|
||||
String valDescriptions[] = new String[curArgs.size()];
|
||||
for (int i = 0; i < curArgs.size(); i++)
|
||||
valDescriptions[i] = (String)curArgs.get(i);
|
||||
if (isDouble) {
|
||||
double values[] = new double[argVals.size()];
|
||||
for (int i = 0; i < argVals.size(); i++)
|
||||
values[i] = ((Double)argVals.get(i)).doubleValue();
|
||||
summary.addData(name, curDescription, valDescriptions, when, values);
|
||||
} else {
|
||||
long values[] = new long[argVals.size()];
|
||||
for (int i = 0; i < argVals.size(); i++)
|
||||
values[i] = ((Long)argVals.get(i)).longValue();
|
||||
summary.addData(name, curDescription, valDescriptions, when, values);
|
||||
}
|
||||
} catch (ParseException pe) {
|
||||
_log.error("Error parsing the data line [" + line + "]", pe);
|
||||
} catch (NumberFormatException nfe) {
|
||||
_log.error("Error parsing the data line [" + line + "]", nfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
_log.error("Error handling the data", e);
|
||||
throw new IOException("Error parsing the data");
|
||||
}
|
||||
if (summary == null)
|
||||
return;
|
||||
summary.coallesceData(monitor.getSummaryDurationHours() * 60*60*1000);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user