forked from I2P_Developers/i2p.i2p
Compare commits
198 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 |
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
|
@@ -1,8 +1,13 @@
|
||||
#
|
||||
# This Makefile is compatible with GNU Make and should work on Linux
|
||||
# (Tested on Debian 3.0)
|
||||
# This Makefile is compatible with GNU Make and should work on Linux (generic)
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating environment
|
||||
#
|
||||
|
||||
OS = LINUX
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
@@ -27,6 +32,7 @@ CC = g++
|
||||
#
|
||||
|
||||
CFLAGS = -g -march=i486 -pipe -Wall
|
||||
CFLAGS += -DOS=$(OS)
|
||||
|
||||
#
|
||||
# Libraries
|
||||
@@ -34,7 +40,7 @@ CFLAGS = -g -march=i486 -pipe -Wall
|
||||
|
||||
CFLAGS += -I$(SAMINCDIR) -I$(TOMCRYPTDIR)
|
||||
LDFLAGS = -L$(SAMLIBDIR) -L$(TOMCRYPTDIR)
|
||||
LIBS = -lsam -ltomcrypt
|
||||
LIBS = -lsam -ltomcrypt -lpthread
|
||||
|
||||
#
|
||||
# Object files
|
||||
@@ -45,11 +51,13 @@ OBJS = $(OBJDIR)/bigint.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)/sha1.o \
|
||||
$(OBJDIR)/thread.o
|
||||
|
||||
#
|
||||
# Build rules
|
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
|
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
|
@@ -42,3 +42,20 @@ Logger::Logger(const string& file)
|
||||
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
|
||||
|
@@ -81,4 +81,8 @@ class Logger {
|
||||
ofstream logf;
|
||||
};
|
||||
|
||||
#ifdef WIN_STRERROR
|
||||
TCHAR* win_strerror(TCHAR* str, size_t size);
|
||||
#endif
|
||||
|
||||
#endif // LOGGER_HPP
|
||||
|
@@ -39,6 +39,13 @@
|
||||
#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
|
||||
*/
|
||||
@@ -49,6 +56,11 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#ifdef WINTHREADS
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
@@ -56,6 +68,10 @@
|
||||
|
||||
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.
|
||||
@@ -71,6 +87,8 @@ using namespace std;
|
||||
/*
|
||||
* 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
|
||||
|
@@ -71,7 +71,7 @@ Sam::Sam(const string& samhost, uint16_t samport, const string& destname,
|
||||
Sam::~Sam(void)
|
||||
{
|
||||
delete peers; // this must be before set_connected(false)!
|
||||
if (get_connected()) {
|
||||
if (is_connected()) {
|
||||
sam_close();
|
||||
set_connected(false);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ Sam::~Sam(void)
|
||||
void Sam::connect(const char* samhost, uint16_t samport, const char* destname,
|
||||
uint_t tunneldepth)
|
||||
{
|
||||
assert(!get_connected());
|
||||
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)
|
||||
@@ -114,7 +114,7 @@ void Sam::load_peers(void)
|
||||
*/
|
||||
void Sam::naming_lookup(const string& name) const
|
||||
{
|
||||
assert(get_connected());
|
||||
assert(is_connected());
|
||||
sam_naming_lookup(name.c_str());
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ void Sam::naming_lookup(const string& name) const
|
||||
*/
|
||||
void Sam::parse_dgram(const string& dest, void* data, size_t size)
|
||||
{
|
||||
assert(get_connected());
|
||||
assert(is_connected());
|
||||
Peer* peer = peers->new_peer(dest);
|
||||
Rpc rpc(peer);
|
||||
rpc.parse(data, size);
|
||||
@@ -140,7 +140,7 @@ void Sam::parse_dgram(const string& dest, void* data, size_t size)
|
||||
*/
|
||||
void Sam::read_buffer(void)
|
||||
{
|
||||
assert(get_connected());
|
||||
assert(is_connected());
|
||||
sam_read_buffer();
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ void Sam::read_buffer(void)
|
||||
*/
|
||||
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
|
||||
}
|
||||
@@ -189,10 +190,10 @@ 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 - may not be true in the
|
||||
else // future
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -55,7 +55,7 @@ class Sam {
|
||||
private:
|
||||
void connect(const char* samhost, uint16_t samport,
|
||||
const char* destname, uint_t tunneldepth);
|
||||
bool get_connected(void) const { return connected; }
|
||||
bool is_connected(void) const { return connected; }
|
||||
|
||||
bool connected;
|
||||
static bool exists;
|
||||
|
@@ -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;
|
||||
|
@@ -90,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() {
|
||||
@@ -120,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,12 +6,11 @@ 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.I2PException;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
@@ -47,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
|
||||
@@ -579,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)
|
||||
|
@@ -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();
|
||||
|
@@ -19,7 +19,7 @@ import net.i2p.heartbeat.PeerData;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
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) {
|
||||
@@ -45,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();
|
||||
@@ -116,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
|
||||
@@ -144,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
|
||||
|
@@ -14,14 +14,21 @@ import net.i2p.util.Log;
|
||||
*
|
||||
*/
|
||||
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
|
||||
|
@@ -18,7 +18,7 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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() {
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import net.i2p.util.Log;
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -69,6 +70,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
private I2PAppContext _context;
|
||||
private static long __tunnelId = 0;
|
||||
private long _tunnelId;
|
||||
private Properties _clientOptions;
|
||||
|
||||
public static final int PACKET_DELAY = 100;
|
||||
|
||||
@@ -104,6 +106,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
_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;
|
||||
@@ -167,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()) {
|
||||
@@ -197,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)) {
|
||||
@@ -262,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
|
||||
@@ -304,7 +336,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
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);
|
||||
@@ -350,7 +382,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
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);
|
||||
@@ -386,7 +418,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
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 {
|
||||
@@ -423,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 {
|
||||
@@ -460,7 +492,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -779,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 {
|
||||
|
@@ -19,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");
|
||||
|
@@ -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() {
|
||||
|
@@ -59,7 +59,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
"Cache-control: no-cache\r\n"+
|
||||
"\r\n"+
|
||||
"<html><body><H1>I2P ERROR: DESTINATION NOT FOUND</H1>"+
|
||||
"That I2P Desitination was not found. Perhaps you pasted in the "+
|
||||
"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>. "+
|
||||
@@ -71,7 +71,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
"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 "+
|
||||
@@ -81,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");
|
||||
@@ -127,7 +127,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
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("//");
|
||||
@@ -226,6 +226,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
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;
|
||||
@@ -365,6 +367,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
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);
|
||||
|
@@ -45,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) {
|
||||
@@ -62,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);
|
||||
}
|
||||
|
||||
@@ -73,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;
|
||||
|
@@ -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[1024];
|
||||
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)
|
||||
|
@@ -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
|
||||
*
|
||||
@@ -35,6 +37,9 @@ class I2PSocketImpl implements I2PSocket {
|
||||
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();
|
||||
|
||||
/**
|
||||
@@ -73,6 +78,9 @@ class I2PSocketImpl implements I2PSocket {
|
||||
out = new I2POutputStream(pin);
|
||||
new I2PSocketRunner(pin);
|
||||
this.localID = localID;
|
||||
_createdOn = I2PAppContext.getGlobalContext().clock().now();
|
||||
_remoteIdSetTime = -1;
|
||||
_closedOn = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,6 +97,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
public void setRemoteID(String id) {
|
||||
synchronized (remoteIDWaiter) {
|
||||
remoteID = id;
|
||||
_remoteIdSetTime = System.currentTimeMillis();
|
||||
remoteIDWaiter.notifyAll();
|
||||
}
|
||||
}
|
||||
@@ -123,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 "
|
||||
@@ -199,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();
|
||||
@@ -214,6 +232,7 @@ class I2PSocketImpl implements I2PSocket {
|
||||
closed = true;
|
||||
closed2 = true;
|
||||
sendClose = false;
|
||||
_closedOn = I2PAppContext.getGlobalContext().clock().now();
|
||||
}
|
||||
out.close();
|
||||
in.notifyClosed();
|
||||
@@ -248,6 +267,12 @@ class I2PSocketImpl implements I2PSocket {
|
||||
_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 + "]: "; }
|
||||
|
||||
//--------------------------------------------------
|
||||
@@ -273,12 +298,15 @@ class I2PSocketImpl implements I2PSocket {
|
||||
throw new RuntimeException("Incorrect read() result");
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix() + "Read called: " + this.hashCode());
|
||||
_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) {
|
||||
@@ -290,10 +318,12 @@ class I2PSocketImpl implements I2PSocket {
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (readTimeout >= 0) {
|
||||
wait(readTimeout);
|
||||
} else {
|
||||
wait();
|
||||
synchronized (I2PSocketImpl.I2PInputStream.this) {
|
||||
if (readTimeout >= 0) {
|
||||
wait(readTimeout);
|
||||
} else {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {}
|
||||
|
||||
@@ -302,7 +332,9 @@ class I2PSocketImpl implements I2PSocket {
|
||||
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);
|
||||
@@ -320,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(getPrefix() + "Insert " + len + " bytes into queue: " + hashCode());
|
||||
bc.append(data, off, len);
|
||||
notifyAll();
|
||||
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 {
|
||||
@@ -414,7 +454,8 @@ class I2PSocketImpl implements I2PSocket {
|
||||
_log.debug(getPrefix() + "Message size is: " + data.length);
|
||||
boolean sent = sendBlock(data);
|
||||
if (!sent) {
|
||||
_log.error(getPrefix() + "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;
|
||||
}
|
||||
@@ -435,9 +476,10 @@ class I2PSocketImpl implements I2PSocket {
|
||||
packetsHandled++;
|
||||
}
|
||||
if ((bc.getCurrentSize() > 0) && (packetsHandled > 1)) {
|
||||
_log.error(getPrefix() + "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;
|
||||
@@ -452,7 +494,8 @@ class I2PSocketImpl implements I2PSocket {
|
||||
byte[] packet = I2PSocketManager.makePacket(getMask(0x02), remoteID, new byte[0]);
|
||||
boolean sent = manager.getSession().sendMessage(remote, packet);
|
||||
if (!sent) {
|
||||
_log.error(getPrefix() + "Error sending close packet to peer");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(getPrefix() + "Error sending close packet to peer");
|
||||
errorOccurred();
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ 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;
|
||||
@@ -24,6 +25,7 @@ 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
|
||||
@@ -33,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
|
||||
@@ -41,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;
|
||||
@@ -57,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() {
|
||||
@@ -82,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) {
|
||||
@@ -95,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;
|
||||
@@ -107,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) {
|
||||
@@ -136,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,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;
|
||||
}
|
||||
@@ -189,11 +223,11 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s = (I2PSocketImpl) _outSockets.get(id);
|
||||
}
|
||||
|
||||
_log.debug("*Disconnect outgoing for socket " + s);
|
||||
_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) {
|
||||
@@ -207,7 +241,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
return;
|
||||
} catch (Exception t) {
|
||||
_log.error("Ignoring error on disconnect for socket " + s, t);
|
||||
_log.error(getName() + ": Ignoring error on disconnect for socket " + s, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,12 +259,13 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
|
||||
// packet send outgoing
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("*Packet send outgoing [" + payload.length + "] for socket " + s);
|
||||
_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");
|
||||
}
|
||||
}
|
||||
@@ -258,7 +293,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
s.setRemoteID(id);
|
||||
}
|
||||
}
|
||||
_log.debug("*Syn! for socket " + s);
|
||||
_log.debug(getName() + ": *Syn! for socket " + s);
|
||||
|
||||
if (!acceptConnections) {
|
||||
// The app did not instantiate an I2PServerSocket
|
||||
@@ -268,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;
|
||||
}
|
||||
|
||||
@@ -282,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()
|
||||
_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
|
||||
@@ -293,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 for socket " + s);
|
||||
_log.warn(getName() + ": Error sending NACK for session creation for socket " + s);
|
||||
}
|
||||
s.internalClose();
|
||||
_context.statManager().addRateData("streaming,nackSent", 1, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -314,7 +352,7 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
}
|
||||
|
||||
_log.debug("*Disconnect incoming for socket " + s);
|
||||
_log.debug(getName() + ": *Disconnect incoming for socket " + s);
|
||||
|
||||
try {
|
||||
if (payload.length == 0 && s != null) {
|
||||
@@ -322,13 +360,13 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -346,13 +384,13 @@ public class I2PSocketManager implements I2PSessionListener {
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("*Packet send incoming [" + payload.length + "] for socket " + s);
|
||||
_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");
|
||||
}
|
||||
}
|
||||
@@ -362,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)
|
||||
@@ -376,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) {
|
||||
@@ -424,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 for socket " + s);
|
||||
_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)
|
||||
if (remoteID == null) {
|
||||
_context.statManager().addRateData("streaming.nackReceived", 1, 1);
|
||||
throw new ConnectException("Connection refused by peer for socket " + s);
|
||||
if ("".equals(remoteID))
|
||||
}
|
||||
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 "
|
||||
_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 "
|
||||
_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();
|
||||
@@ -458,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) + " for socket " + s, ex);
|
||||
_log.error(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@@ -466,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) + " for socket " + s, ex);
|
||||
_log.info(getName() + ": Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
|
||||
synchronized (lock) {
|
||||
_outSockets.remove(s.getLocalID());
|
||||
}
|
||||
@@ -474,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());
|
||||
}
|
||||
}
|
||||
@@ -515,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();
|
||||
}
|
||||
@@ -525,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 {
|
||||
@@ -541,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,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()) + "\" [" + sock + "]");
|
||||
_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" />
|
||||
|
@@ -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:lib/javax.servlet.jar" />
|
||||
<javac srcdir="./src" debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj" classpath="../../../core/java/build/i2p.jar:lib/javax.servlet.jar" />
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<war destfile="./build/phttprelay.war" webxml="web.xml">
|
||||
|
57
apps/routerconsole/java/build.xml
Normal file
57
apps/routerconsole/java/build.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project basedir="." default="all" name="routerconsole">
|
||||
<target name="all" depends="clean, build" />
|
||||
<target name="build" depends="builddep, jar" />
|
||||
<target name="builddep" depends="jetty" >
|
||||
<ant dir="../../../router/java/" target="build" />
|
||||
<!-- router will build core -->
|
||||
</target>
|
||||
<target name="jetty">
|
||||
<untar src="jetty-4.2.21-min.tar.bz2" compression="bzip2" dest="." />
|
||||
<ant dir="jetty-4.2.21-min/extra/jdk1.2/" target="all" />
|
||||
</target>
|
||||
<target name="compile">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/obj" />
|
||||
<javac
|
||||
srcdir="./src"
|
||||
debug="true" deprecation="on" source="1.3" target="1.3"
|
||||
destdir="./build/obj"
|
||||
classpath="../../../core/java/build/i2p.jar:../../../router/java/build/router.jar:jetty-4.2.21-min/extra/lib/org.mortbay.jetty-jdk1.2.jar" />
|
||||
</target>
|
||||
<target name="jar" depends="compile">
|
||||
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="i2p.jar router.jar" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<ant target="war" />
|
||||
</target>
|
||||
<target name="war">
|
||||
<war destfile="build/routerconsole.war" webxml="../jsp/web.xml"
|
||||
basedir="../jsp/" excludes="web.xml">
|
||||
</war>
|
||||
</target>
|
||||
<target name="javadoc">
|
||||
<mkdir dir="./build" />
|
||||
<mkdir dir="./build/javadoc" />
|
||||
<javadoc
|
||||
sourcepath="./src:../../../core/java/src:../../router/java/src" destdir="./build/javadoc"
|
||||
packagenames="*"
|
||||
use="true"
|
||||
splitindex="true"
|
||||
windowtitle="Router Console" />
|
||||
</target>
|
||||
<target name="clean">
|
||||
<delete dir="./build" />
|
||||
</target>
|
||||
<target name="cleandep" depends="clean">
|
||||
<!-- router will clean core -->
|
||||
<ant dir="../../../router/java/" target="distclean" />
|
||||
</target>
|
||||
<target name="distclean" depends="clean">
|
||||
<!-- router will clean core -->
|
||||
<ant dir="../../../router/java/" target="distclean" />
|
||||
<delete dir="./jetty-4.2.21-min" />
|
||||
</target>
|
||||
</project>
|
@@ -0,0 +1,38 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class ConfigAdvancedHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigAdvancedHelper() {}
|
||||
|
||||
public String getSettings() {
|
||||
StringBuffer buf = new StringBuffer(4*1024);
|
||||
Set names = _context.router().getConfigSettings();
|
||||
TreeSet sortedNames = new TreeSet(names);
|
||||
for (Iterator iter = sortedNames.iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
String val = _context.router().getConfigSetting(name);
|
||||
buf.append(name).append('=').append(val).append('\n');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.ClientTunnelSettings;
|
||||
|
||||
public class ConfigClientsHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** copied from the package private {@link net.i2p.router.tunnelmanager.TunnelPool} */
|
||||
public final static String TARGET_CLIENTS_PARAM = "router.targetClients";
|
||||
/** copied from the package private {@link net.i2p.router.tunnelmanager.TunnelPool} */
|
||||
public final static int TARGET_CLIENTS_DEFAULT = 3;
|
||||
|
||||
public ConfigClientsHelper() {}
|
||||
|
||||
public String getClientCountSelectBox() {
|
||||
int count = TARGET_CLIENTS_DEFAULT;
|
||||
String val = _context.router().getConfigSetting(TARGET_CLIENTS_PARAM);
|
||||
if (val != null) {
|
||||
try {
|
||||
count = Integer.parseInt(val);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore, use default from above
|
||||
}
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<select name=\"clientcount\">\n");
|
||||
for (int i = 0; i < 5; i++) {
|
||||
buf.append("<option value=\"").append(i).append("\" ");
|
||||
if (count == i)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">").append(i).append("</option>\n");
|
||||
}
|
||||
if (count >= 5) {
|
||||
buf.append("<option value=\"").append(count);
|
||||
buf.append("\" selected>").append(count);
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
buf.append("</select>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getTunnelCountSelectBox() {
|
||||
int count = ClientTunnelSettings.DEFAULT_NUM_INBOUND;
|
||||
String val = _context.router().getConfigSetting(ClientTunnelSettings.PROP_NUM_INBOUND);
|
||||
if (val != null) {
|
||||
try {
|
||||
count = Integer.parseInt(val);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore, use default from above
|
||||
}
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<select name=\"tunnelcount\">\n");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
buf.append("<option value=\"").append(i).append("\" ");
|
||||
if (count == i)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">").append(i).append("</option>\n");
|
||||
}
|
||||
if (count >= 4) {
|
||||
buf.append("<option value=\"").append(count);
|
||||
buf.append("\" selected>").append(count);
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
buf.append("</select>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getTunnelDepthSelectBox() {
|
||||
int count = ClientTunnelSettings.DEFAULT_DEPTH_INBOUND;
|
||||
String val = _context.router().getConfigSetting(ClientTunnelSettings.PROP_DEPTH_INBOUND);
|
||||
if (val != null) {
|
||||
try {
|
||||
count = Integer.parseInt(val);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore, use default from above
|
||||
}
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<select name=\"tunneldepth\">\n");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
buf.append("<option value=\"").append(i).append("\" ");
|
||||
if (count == i)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">").append(i).append("</option>\n");
|
||||
}
|
||||
if (count >= 4) {
|
||||
buf.append("<option value=\"").append(count);
|
||||
buf.append("\" selected>").append(count);
|
||||
buf.append("</option>\n");
|
||||
}
|
||||
buf.append("</select>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,113 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class ConfigLoggingHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigLoggingHelper() {}
|
||||
|
||||
public String getLogFilePattern() {
|
||||
return _context.logManager().getBaseLogfilename();
|
||||
}
|
||||
public String getRecordPattern() {
|
||||
return new String(_context.logManager().getFormat());
|
||||
}
|
||||
public String getDatePattern() {
|
||||
return _context.logManager().getDateFormatPattern();
|
||||
}
|
||||
public String getMaxFileSize() {
|
||||
int bytes = _context.logManager().getFileSize();
|
||||
if (bytes == 0) return "1m";
|
||||
if (bytes > 1024*1024*1024)
|
||||
return (bytes/(1024*1024*1024)) + "g";
|
||||
else if (bytes > 1024*1024)
|
||||
return (bytes/(1024*1024)) + "m";
|
||||
else
|
||||
return (bytes/(1024)) + "k";
|
||||
}
|
||||
public String getLogLevelTable() {
|
||||
StringBuffer buf = new StringBuffer(32*1024);
|
||||
buf.append("<textarea rows=\"20\" cols=\"80\">");
|
||||
List logs = _context.logManager().getLogs();
|
||||
TreeMap sortedLogs = new TreeMap();
|
||||
for (int i = 0; i < logs.size(); i++) {
|
||||
Log l = (Log)logs.get(i);
|
||||
sortedLogs.put(l.getName(), l);
|
||||
}
|
||||
int i = 0;
|
||||
for (Iterator iter = sortedLogs.values().iterator(); iter.hasNext(); i++) {
|
||||
Log l = (Log)iter.next();
|
||||
buf.append(l.getName()).append('=');
|
||||
buf.append(Log.toLevelString(l.getMinimumPriority()));
|
||||
buf.append("\n");
|
||||
}
|
||||
buf.append("</textarea><br />\n");
|
||||
buf.append("<i>Valid levels are DEBUG, INFO, WARN, ERROR, CRIT</i>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
public String getLogLevelTableDetail() {
|
||||
StringBuffer buf = new StringBuffer(8*1024);
|
||||
buf.append("<table border=\"1\">\n");
|
||||
buf.append("<tr><td>Package/class</td><td>Level</td></tr>\n");
|
||||
List logs = _context.logManager().getLogs();
|
||||
TreeMap sortedLogs = new TreeMap();
|
||||
for (int i = 0; i < logs.size(); i++) {
|
||||
Log l = (Log)logs.get(i);
|
||||
sortedLogs.put(l.getName(), l);
|
||||
}
|
||||
int i = 0;
|
||||
for (Iterator iter = sortedLogs.values().iterator(); iter.hasNext(); i++) {
|
||||
Log l = (Log)iter.next();
|
||||
buf.append("<tr>\n <td><input size=\"50\" type=\"text\" name=\"logrecord.");
|
||||
buf.append(i).append(".package\" value=\"").append(l.getName());
|
||||
buf.append("\" /></td>\n");
|
||||
buf.append("<td><select name=\"logrecord.").append(i);
|
||||
buf.append(".level\">\n\t");
|
||||
buf.append("<option value=\"DEBUG\" ");
|
||||
if (l.getMinimumPriority() == Log.DEBUG)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">Debug</option>\n\t");
|
||||
buf.append("<option value=\"INFO\" ");
|
||||
if (l.getMinimumPriority() == Log.INFO)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">Info</option>\n\t");
|
||||
buf.append("<option value=\"WARN\" ");
|
||||
if (l.getMinimumPriority() == Log.WARN)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">Warn</option>\n\t");
|
||||
buf.append("<option value=\"ERROR\" ");
|
||||
if (l.getMinimumPriority() == Log.ERROR)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">Error</option>\n\t");
|
||||
buf.append("<option value=\"CRIT\" ");
|
||||
if (l.getMinimumPriority() == Log.CRIT)
|
||||
buf.append("selected=\"true\" ");
|
||||
buf.append(">Critical</option>\n\t");
|
||||
buf.append("</select></td>\n</tr>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.ClientTunnelSettings;
|
||||
|
||||
public class ConfigNetHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ConfigNetHelper() {}
|
||||
|
||||
/** copied from various private TCP components */
|
||||
private final static String PROP_I2NP_TCP_HOSTNAME = "i2np.tcp.hostname";
|
||||
private final static String PROP_I2NP_TCP_PORT = "i2np.tcp.port";
|
||||
|
||||
public String getHostname() {
|
||||
return _context.getProperty(PROP_I2NP_TCP_HOSTNAME);
|
||||
}
|
||||
public String getPort() {
|
||||
int port = 8887;
|
||||
String val = _context.getProperty(PROP_I2NP_TCP_PORT);
|
||||
if (val != null) {
|
||||
try {
|
||||
port = Integer.parseInt(val);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore, use default from above
|
||||
}
|
||||
}
|
||||
return "" + port;
|
||||
}
|
||||
|
||||
public String getEnableTimeSyncChecked() {
|
||||
String enabled = System.getProperty("timestamper.enabled");
|
||||
if ( (enabled == null) || (!"true".equals(enabled)) )
|
||||
return "";
|
||||
else
|
||||
return " checked ";
|
||||
}
|
||||
|
||||
public static final String PROP_INBOUND_KBPS = "i2np.bandwidth.inboundKBytesPerSecond";
|
||||
public static final String PROP_OUTBOUND_KBPS = "i2np.bandwidth.outboundKBytesPerSecond";
|
||||
public static final String PROP_INBOUND_BURST = "i2np.bandwidth.inboundBurstKBytes";
|
||||
public static final String PROP_OUTBOUND_BURST = "i2np.bandwidth.outboundBurstKBytes";
|
||||
|
||||
public String getInboundRate() {
|
||||
String rate = _context.getProperty(PROP_INBOUND_KBPS);
|
||||
if (rate != null)
|
||||
return rate;
|
||||
else
|
||||
return "-1";
|
||||
}
|
||||
public String getOutboundRate() {
|
||||
String rate = _context.getProperty(PROP_OUTBOUND_KBPS);
|
||||
if (rate != null)
|
||||
return rate;
|
||||
else
|
||||
return "Unlimited";
|
||||
}
|
||||
public String getInboundBurstFactorBox() {
|
||||
String rate = _context.getProperty(PROP_INBOUND_KBPS);
|
||||
String burst = _context.getProperty(PROP_INBOUND_BURST);
|
||||
int numSeconds = 1;
|
||||
if ( (burst != null) && (rate != null) ) {
|
||||
int rateKBps = 0;
|
||||
int burstKB = 0;
|
||||
try {
|
||||
rateKBps = Integer.parseInt(rate);
|
||||
burstKB = Integer.parseInt(burst);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore
|
||||
}
|
||||
if ( (rateKBps > 0) && (burstKB > 0) ) {
|
||||
numSeconds = burstKB / rateKBps;
|
||||
}
|
||||
}
|
||||
return getBurstFactor(numSeconds, "inboundburstfactor");
|
||||
}
|
||||
|
||||
public String getOutboundBurstFactorBox() {
|
||||
String rate = _context.getProperty(PROP_OUTBOUND_KBPS);
|
||||
String burst = _context.getProperty(PROP_OUTBOUND_BURST);
|
||||
int numSeconds = 1;
|
||||
if ( (burst != null) && (rate != null) ) {
|
||||
int rateKBps = 0;
|
||||
int burstKB = 0;
|
||||
try {
|
||||
rateKBps = Integer.parseInt(rate);
|
||||
burstKB = Integer.parseInt(burst);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// ignore
|
||||
}
|
||||
if ( (rateKBps > 0) && (burstKB > 0) ) {
|
||||
numSeconds = burstKB / rateKBps;
|
||||
}
|
||||
}
|
||||
return getBurstFactor(numSeconds, "outboundburstfactor");
|
||||
}
|
||||
|
||||
private static String getBurstFactor(int numSeconds, String name) {
|
||||
StringBuffer buf = new StringBuffer(256);
|
||||
buf.append("<select name=\"").append(name).append("\">\n");
|
||||
for (int i = 1; i < 10; i++) {
|
||||
buf.append("<option value=\"").append(i).append("\" ");
|
||||
if ( (i == numSeconds) || (i == 10) )
|
||||
buf.append("selected ");
|
||||
buf.append(">");
|
||||
if (i == 1)
|
||||
buf.append("1 second (no burst)</option>\n");
|
||||
else
|
||||
buf.append(i).append(" seconds</option>\n");
|
||||
}
|
||||
buf.append("</select>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.List;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
class ContextHelper {
|
||||
public static RouterContext getContext(String contextId) {
|
||||
List contexts = RouterContext.listContexts();
|
||||
if ( (contexts == null) || (contexts.size() <= 0) )
|
||||
throw new IllegalStateException("No contexts? wtf");
|
||||
if ( (contextId == null) || (contextId.trim().length() <= 0) )
|
||||
return (RouterContext)contexts.get(0);
|
||||
for (int i = 0; i < contexts.size(); i++) {
|
||||
RouterContext context = (RouterContext)contexts.get(i);
|
||||
Hash hash = context.routerHash();
|
||||
if (hash == null) continue;
|
||||
if (hash.toBase64().startsWith(contextId))
|
||||
return context;
|
||||
}
|
||||
// not found, so just give them the first we can find
|
||||
return (RouterContext)contexts.get(0);
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class LogsHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public LogsHelper() {}
|
||||
|
||||
public String getLogs() {
|
||||
List msgs = _context.logManager().getBuffer().getMostRecentMessages();
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h2>Most recent console messages:</h2><ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = 0; i < msgs.size(); i++) {
|
||||
String msg = (String)msgs.get(i);
|
||||
buf.append("<li>");
|
||||
buf.append(msg);
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</code></ul>\n");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class NavHelper {
|
||||
private static Map _apps = new HashMap();
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public NavHelper() {}
|
||||
|
||||
/**
|
||||
* To register a new client application so that it shows up on the router
|
||||
* console's nav bar, it should be registered with this singleton.
|
||||
*
|
||||
* @param name pretty name the app will be called in the link
|
||||
* @param path full path pointing to the application's root
|
||||
* (e.g. /i2ptunnel/index.jsp)
|
||||
*/
|
||||
public static void registerApp(String name, String path) {
|
||||
_apps.put(name, path);
|
||||
}
|
||||
public static void unregisterApp(String name) {
|
||||
_apps.remove(name);
|
||||
}
|
||||
|
||||
public String getClientAppLinks() {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
for (Iterator iter = _apps.keySet().iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
String path = (String)_apps.get(name);
|
||||
buf.append("<a href=\"").append(path).append("\">");
|
||||
buf.append(name).append("</a> |");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class NetDbHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public NetDbHelper() {}
|
||||
|
||||
public String getNetDbSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024);
|
||||
try {
|
||||
_context.netDb().renderStatusHTML(baos);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
public class ProfilesHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ProfilesHelper() {}
|
||||
|
||||
public String getProfileSummary() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(16*1024);
|
||||
try {
|
||||
_context.profileOrganizer().renderStatusHTML(baos);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.util.MultiException;
|
||||
|
||||
public class RouterConsoleRunner {
|
||||
private Server _server;
|
||||
private String _listenPort = "7657";
|
||||
private String _listenHost = "0.0.0.0";
|
||||
private String _webAppsDir = "./webapps/";
|
||||
|
||||
public RouterConsoleRunner(String args[]) {
|
||||
if (args.length == 3) {
|
||||
_listenPort = args[0].trim();
|
||||
_listenHost = args[1].trim();
|
||||
_webAppsDir = args[2].trim();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
RouterConsoleRunner runner = new RouterConsoleRunner(args);
|
||||
runner.startConsole();
|
||||
}
|
||||
|
||||
public void startConsole() {
|
||||
_server = new Server();
|
||||
try {
|
||||
_server.addListener(_listenHost + ':' + _listenPort);
|
||||
_server.setRootWebApp("routerconsole");
|
||||
_server.addWebApplications(_webAppsDir);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
try {
|
||||
_server.start();
|
||||
} catch (MultiException me) {
|
||||
me.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopConsole() {
|
||||
try {
|
||||
_server.stop();
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,377 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.stat.Rate;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
|
||||
/**
|
||||
* Simple helper to query the appropriate router for data necessary to render
|
||||
* the summary sections on the router console.
|
||||
*/
|
||||
public class SummaryHelper {
|
||||
private RouterContext _context;
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public void setContextId(String contextId) {
|
||||
try {
|
||||
_context = ContextHelper.getContext(contextId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the shortened 4 character ident for the router located within
|
||||
* the current JVM at the given context.
|
||||
*
|
||||
*/
|
||||
public String getIdent() {
|
||||
if (_context == null) return "[no router]";
|
||||
|
||||
if (_context.routerHash() != null)
|
||||
return _context.routerHash().toBase64().substring(0, 4);
|
||||
else
|
||||
return "[unknown]";
|
||||
}
|
||||
/**
|
||||
* Retrieve the version number of the router.
|
||||
*
|
||||
*/
|
||||
public String getVersion() {
|
||||
return RouterVersion.VERSION;
|
||||
}
|
||||
/**
|
||||
* Retrieve a pretty printed uptime count (ala 4d or 7h or 39m)
|
||||
*
|
||||
*/
|
||||
public String getUptime() {
|
||||
if (_context == null) return "[no router]";
|
||||
|
||||
Router router = _context.router();
|
||||
if (router == null)
|
||||
return "[not up]";
|
||||
else
|
||||
return DataHelper.formatDuration(router.getUptime());
|
||||
}
|
||||
|
||||
/**
|
||||
* How many active peers the router has.
|
||||
*
|
||||
*/
|
||||
public int getActivePeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countActivePeers();
|
||||
}
|
||||
/**
|
||||
* How many active peers the router ranks as fast.
|
||||
*
|
||||
*/
|
||||
public int getFastPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countFastPeers();
|
||||
}
|
||||
/**
|
||||
* How many active peers the router ranks as having a high capacity.
|
||||
*
|
||||
*/
|
||||
public int getHighCapacityPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countHighCapacityPeers();
|
||||
}
|
||||
/**
|
||||
* How many active peers the router ranks as well integrated.
|
||||
*
|
||||
*/
|
||||
public int getWellIntegratedPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countWellIntegratedPeers();
|
||||
}
|
||||
/**
|
||||
* How many peers the router ranks as failing.
|
||||
*
|
||||
*/
|
||||
public int getFailingPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countFailingPeers();
|
||||
}
|
||||
/**
|
||||
* How many peers totally suck.
|
||||
*
|
||||
*/
|
||||
public int getShitlistedPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.shitlist().getRouterCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* How fast we have been receiving data over the last minute (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getInboundMinuteKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.receiveMessageSize");
|
||||
Rate rate = receiveRate.getRate(60*1000);
|
||||
double bytes = rate.getLastTotalValue();
|
||||
double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d);
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
return fmt.format(bps);
|
||||
}
|
||||
/**
|
||||
* How fast we have been sending data over the last minute (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getOutboundMinuteKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.sendMessageSize");
|
||||
Rate rate = receiveRate.getRate(60*1000);
|
||||
double bytes = rate.getLastTotalValue();
|
||||
double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d);
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
return fmt.format(bps);
|
||||
}
|
||||
|
||||
/**
|
||||
* How fast we have been receiving data over the last 5 minutes (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getInboundFiveMinuteKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.receiveMessageSize");
|
||||
Rate rate = receiveRate.getRate(5*60*1000);
|
||||
double bytes = rate.getLastTotalValue();
|
||||
double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d);
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
return fmt.format(bps);
|
||||
}
|
||||
|
||||
/**
|
||||
* How fast we have been sending data over the last 5 minutes (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getOutboundFiveMinuteKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("transport.sendMessageSize");
|
||||
Rate rate = receiveRate.getRate(5*60*1000);
|
||||
double bytes = rate.getLastTotalValue();
|
||||
double bps = (bytes*1000.0d)/(rate.getPeriod()*1024.0d);
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
return fmt.format(bps);
|
||||
}
|
||||
|
||||
/**
|
||||
* How fast we have been receiving data since the router started (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getInboundLifetimeKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
long received = _context.bandwidthLimiter().getTotalAllocatedInboundBytes();
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
// we use the unadjusted time, since thats what getWhenStarted is based off
|
||||
long lifetime = _context.clock().now()-_context.clock().getOffset()
|
||||
- _context.router().getWhenStarted();
|
||||
lifetime /= 1000;
|
||||
if (received > 0) {
|
||||
double receivedKBps = received / (lifetime*1024.0);
|
||||
return fmt.format(receivedKBps);
|
||||
} else {
|
||||
return "0.0";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How fast we have been sending data since the router started (pretty printed
|
||||
* string with 2 decimal places representing the KBps)
|
||||
*
|
||||
*/
|
||||
public String getOutboundLifetimeKBps() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
long sent = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes();
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
// we use the unadjusted time, since thats what getWhenStarted is based off
|
||||
long lifetime = _context.clock().now()-_context.clock().getOffset()
|
||||
- _context.router().getWhenStarted();
|
||||
lifetime /= 1000;
|
||||
if (sent > 0) {
|
||||
double sendKBps = sent / (lifetime*1024.0);
|
||||
return fmt.format(sendKBps);
|
||||
} else {
|
||||
return "0.0";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How much data have we received since the router started (pretty printed
|
||||
* string with 2 decimal places and the appropriate units - GB/MB/KB/bytes)
|
||||
*
|
||||
*/
|
||||
public String getInboundTransferred() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
long received = _context.bandwidthLimiter().getTotalAllocatedInboundBytes();
|
||||
|
||||
return getTransferred(received);
|
||||
}
|
||||
|
||||
/**
|
||||
* How much data have we sent since the router started (pretty printed
|
||||
* string with 2 decimal places and the appropriate units - GB/MB/KB/bytes)
|
||||
*
|
||||
*/
|
||||
public String getOutboundTransferred() {
|
||||
if (_context == null)
|
||||
return "0.0";
|
||||
|
||||
long sent = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes();
|
||||
return getTransferred(sent);
|
||||
}
|
||||
|
||||
private static String getTransferred(long bytes) {
|
||||
int scale = 0;
|
||||
if (bytes > 1024*1024*1024) {
|
||||
// gigs transferred
|
||||
scale = 3;
|
||||
bytes /= (1024*1024*1024);
|
||||
} else if (bytes > 1024*1024) {
|
||||
// megs transferred
|
||||
scale = 2;
|
||||
bytes /= (1024*1024);
|
||||
} else if (bytes > 1024) {
|
||||
// kbytes transferred
|
||||
scale = 1;
|
||||
bytes /= 1024;
|
||||
} else {
|
||||
scale = 0;
|
||||
}
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
String str = fmt.format(bytes);
|
||||
switch (scale) {
|
||||
case 1: return str + "KB";
|
||||
case 2: return str + "MB";
|
||||
case 3: return str + "GB";
|
||||
default: return bytes + "bytes";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How many free inbound tunnels we have.
|
||||
*
|
||||
* @param contextId begging few characters of the routerHash, or null to pick
|
||||
* the first one we come across.
|
||||
*/
|
||||
public int getInboundTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getFreeTunnelCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* How many active outbound tunnels we have.
|
||||
*
|
||||
*/
|
||||
public int getOutboundTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getOutboundTunnelCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* How many tunnels we are participating in.
|
||||
*
|
||||
*/
|
||||
public int getParticipatingTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getParticipatingCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* How lagged our job queue is over the last minute (pretty printed with
|
||||
* the units attached)
|
||||
*
|
||||
*/
|
||||
public String getJobLag() {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate lagRate = _context.statManager().getRate("jobQueue.jobLag").getRate(60*1000);
|
||||
return ((int)lagRate.getAverageValue()) + "ms";
|
||||
}
|
||||
|
||||
/**
|
||||
* How long it takes us to pump out a message, averaged over the last minute
|
||||
* (pretty printed with the units attached)
|
||||
*
|
||||
*/
|
||||
public String getMessageDelay() {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate delayRate = _context.statManager().getRate("transport.sendProcessingTime").getRate(60*1000);
|
||||
return ((int)delayRate.getAverageValue()) + "ms";
|
||||
}
|
||||
|
||||
/**
|
||||
* How long it takes us to test our tunnels, averaged over the last 10 minutes
|
||||
* (pretty printed with the units attached)
|
||||
*
|
||||
*/
|
||||
public String getTunnelLag() {
|
||||
if (_context == null)
|
||||
return "0ms";
|
||||
|
||||
Rate lagRate = _context.statManager().getRate("tunnel.testSuccessTime").getRate(10*60*1000);
|
||||
return ((int)lagRate.getAverageValue()) + "ms";
|
||||
}
|
||||
}
|
53
apps/routerconsole/jsp/config.jsp
Normal file
53
apps/routerconsole/jsp/config.jsp
Normal file
@@ -0,0 +1,53 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - logs</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigNetHelper" id="nethelper" scope="request" />
|
||||
<jsp:setProperty name="nethelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsp" %>
|
||||
<form action="config.jsp" method="POST">
|
||||
<b>External hostname/IP address:</b>
|
||||
<input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" />
|
||||
<input type="submit" name="guesshost" value="Guess" /><br />
|
||||
<b>Externally reachable TCP port:</b>
|
||||
<input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br />
|
||||
<i>The hostname/IP address and TCP port must be reachable from the outside world. If
|
||||
you are behind a firewall or NAT, this means you must poke a hole for this port. If
|
||||
you are using DHCP and do not have a static IP address, you must use a service like
|
||||
<a href="http://dyndns.org/">dyndns</a>. The "guess" functionality makes an HTTP request
|
||||
to <a href="http://www.whatismyip.com/">www.whatismyip.com</a>.</i>
|
||||
<hr />
|
||||
<b>Enable internal time synchronization?</b> <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
|
||||
<i>If disabled, your machine <b>must</b> be NTP synchronized</i>
|
||||
<hr />
|
||||
<b>Bandwidth limiter</b><br />
|
||||
<b>Inbound rate</b>:
|
||||
<input name="inboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="inboundRate" />" /> KBytes per second<br />
|
||||
<b>Inbound burst duration:</b>
|
||||
<jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br />
|
||||
<b>Outbound rate:</b>
|
||||
<input name="outboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="outboundRate" />" /> KBytes per second<br />
|
||||
<b>Outbound burst duration:</b>
|
||||
<jsp:getProperty name="nethelper" property="outboundBurstFactorBox" /><br />
|
||||
<i>A negative rate means there is no limit</i><br />
|
||||
<hr />
|
||||
<b>Reseed</b> (from <input name="reseedfrom" type="text" size="40" value="http://dev.i2p.net/i2pdb/" />):
|
||||
<input type="submit" name="reseed" value="now" /><br />
|
||||
<hr />
|
||||
<input type="submit" value="Save changes" /> <input type="reset" value="Cancel" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
26
apps/routerconsole/jsp/configadvanced.jsp
Normal file
26
apps/routerconsole/jsp/configadvanced.jsp
Normal file
@@ -0,0 +1,26 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - config advanced</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigAdvancedHelper" id="advancedhelper" scope="request" />
|
||||
<jsp:setProperty name="advancedhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsp" %>
|
||||
<form action="configadvanced.jsp" method="POST">
|
||||
<textarea rows="20" cols="80" name="config"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br />
|
||||
<input type="submit" value="Apply" /> <input type="reset" value="Cancel" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
32
apps/routerconsole/jsp/configclients.jsp
Normal file
32
apps/routerconsole/jsp/configclients.jsp
Normal file
@@ -0,0 +1,32 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - config clients</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigClientsHelper" id="clientshelper" scope="request" />
|
||||
<jsp:setProperty name="clientshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsp" %>
|
||||
<form action="configclients.jsp" method="POST">
|
||||
<b>Estimated number of clients/destinations:</b>
|
||||
<jsp:getProperty name="clientshelper" property="clientCountSelectBox" /><br />
|
||||
<b>Default number of inbound tunnels per client:</b>
|
||||
<jsp:getProperty name="clientshelper" property="tunnelCountSelectBox" /><br />
|
||||
<b>Default number of hops per tunnel:</b>
|
||||
<jsp:getProperty name="clientshelper" property="tunnelDepthSelectBox" /><br />
|
||||
<hr />
|
||||
<input type="submit" value="Save changes" /> <input type="reset" value="Cancel" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
39
apps/routerconsole/jsp/configlogging.jsp
Normal file
39
apps/routerconsole/jsp/configlogging.jsp
Normal file
@@ -0,0 +1,39 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - config clients</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
<jsp:useBean class="net.i2p.router.web.ConfigLoggingHelper" id="logginghelper" scope="request" />
|
||||
<jsp:setProperty name="logginghelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
<%@include file="confignav.jsp" %>
|
||||
<form action="configlogging.jsp" method="POST">
|
||||
<b>Logging filename:</b>
|
||||
<input type="text" name="logfilename" size="40" value="<jsp:getProperty name="logginghelper" property="logFilePattern" />" /><br />
|
||||
<i>(the symbol '#' will be replaced during log rotation)</i><br />
|
||||
<b>Log record format:</b>
|
||||
<input type="text" name="logformat" size="20" value="<jsp:getProperty name="logginghelper" property="recordPattern" />" /><br />
|
||||
<i>(use 'd' = date, 'c' = class, 't' = thread, 'p' = priority, 'm' = message)</i><br />
|
||||
<b>Log date format:</b>
|
||||
<input type="text" name="logdateformat" size="20" value="<jsp:getProperty name="logginghelper" property="datePattern" />" /><br />
|
||||
<i>('MM' = month, 'dd' = day, 'HH' = hour, 'mm' = minute, 'ss' = second, 'SSS' = millisecond)</i><br />
|
||||
<b>Max log file size:</b>
|
||||
<input type="text" name="logfilesize" size="4" value="<jsp:getProperty name="logginghelper" property="maxFileSize" />" /><br />
|
||||
<hr />
|
||||
<b>Log levels:</b> <br />
|
||||
<jsp:getProperty name="logginghelper" property="logLevelTable" />
|
||||
<hr />
|
||||
<input type="submit" value="Apply changes" /> <input type="submit" value="Apply and Save" /> <input type="reset" value="Cancel" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
8
apps/routerconsole/jsp/confignav.jsp
Normal file
8
apps/routerconsole/jsp/confignav.jsp
Normal file
@@ -0,0 +1,8 @@
|
||||
<h4><% if (request.getRequestURI().indexOf("config.jsp") != -1) {
|
||||
%>Network | <% } else { %><a href="config.jsp">Network</a> | <% }
|
||||
if (request.getRequestURI().indexOf("configclients.jsp") != -1) {
|
||||
%>Clients | <% } else { %><a href="configclients.jsp">Clients</a> | <% }
|
||||
if (request.getRequestURI().indexOf("configlogging.jsp") != -1) {
|
||||
%>Logging | <% } else { %><a href="configlogging.jsp">Logging</a> | <% }
|
||||
if (request.getRequestURI().indexOf("configadvanced.jsp") != -1) {
|
||||
%>Advanced | <% } else { %><a href="configadvanced.jsp">Advanced</a> | <% } %></h4>
|
60
apps/routerconsole/jsp/default.css
Normal file
60
apps/routerconsole/jsp/default.css
Normal file
@@ -0,0 +1,60 @@
|
||||
body {
|
||||
font-family: Verdana, Tahoma, Helvetica, sans-serif;
|
||||
margin: 1em 0em;
|
||||
padding: 0em;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.logo {
|
||||
float: left;
|
||||
left: 1em;
|
||||
top: 1em;
|
||||
margin: 0em;
|
||||
padding: .5em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.routersummary {
|
||||
/* width: 8em; */
|
||||
/* height: 5em; */
|
||||
/* position: fixed; */
|
||||
float: left;
|
||||
/* left: 1em; */
|
||||
/* top: 1em; */
|
||||
margin: 0em;
|
||||
padding: .5em;
|
||||
text-align: left;
|
||||
border: medium solid #efefff;
|
||||
background-color: #fafaff;
|
||||
color: inherit;
|
||||
font-size: small;
|
||||
clear: left; /* fixes a bug in Opera */
|
||||
}
|
||||
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 12em;
|
||||
padding: .5em 1em;
|
||||
background-color: #ffefef;
|
||||
border: medium solid #ffafaf;
|
||||
text-align: left;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
div.main {
|
||||
margin: 0em 1em 1em 12em;
|
||||
padding: .5em 1em;
|
||||
background-color: #ffffef;
|
||||
border: medium solid #ffffd0;
|
||||
text-align: left;
|
||||
color: inherit;
|
||||
}
|
26
apps/routerconsole/jsp/help.jsp
Normal file
26
apps/routerconsole/jsp/help.jsp
Normal file
@@ -0,0 +1,26 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - logs</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
hmm. we should probably have some help text here.<br />
|
||||
This "routerconsole" application runs on top of a trimmed down <a href="jetty.mortbay.com/jetty/index.html">Jetty</a>
|
||||
instance (trimmed down, as in, we do not include the demo apps or other add-ons), allowing you to deploy standard
|
||||
JSP/Servlet web applications into your router. Jetty in turn makes use of Apache's javax.servlet (javax.servlet.jar)
|
||||
implementation, as well as their xerces-j XML parser (xerces.jar). Their XML parser requires the Sun XML
|
||||
APIs (JAXP) which is included in binary form (xml-apis.jar) as required by their binary code license.
|
||||
This product includes software developed by the Apache Software Foundation (http://www.apache.org/). See the
|
||||
<a href="http://www.i2p.net/">I2P</a> site or the source for more license details.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
apps/routerconsole/jsp/i2plogo.png
Normal file
BIN
apps/routerconsole/jsp/i2plogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 925 B |
19
apps/routerconsole/jsp/index.jsp
Normal file
19
apps/routerconsole/jsp/index.jsp
Normal file
@@ -0,0 +1,19 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - home</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
<h2>Welcome to your router console</h2>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
21
apps/routerconsole/jsp/logs.jsp
Normal file
21
apps/routerconsole/jsp/logs.jsp
Normal file
@@ -0,0 +1,21 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - logs</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:getProperty name="logsHelper" property="logs" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
18
apps/routerconsole/jsp/nav.jsp
Normal file
18
apps/routerconsole/jsp/nav.jsp
Normal file
@@ -0,0 +1,18 @@
|
||||
<%
|
||||
if (request.getParameter("i2p.contextId") != null) {
|
||||
session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
|
||||
}%>
|
||||
|
||||
<div class="logo">
|
||||
<a href="index.jsp"><img src="i2plogo.png" alt="Router Console" width="187" height="35" /></a><br />
|
||||
[<a href="config.jsp">configuration</a> | <a href="help.jsp">help</a>]
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
<a href="profiles.jsp">Profiles</a> |
|
||||
<a href="netdb.jsp">Network Database</a> |
|
||||
<a href="logs.jsp">Logs</a>
|
||||
<jsp:useBean class="net.i2p.router.web.NavHelper" id="navhelper" scope="request" />
|
||||
<jsp:setProperty name="navhelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:getProperty name="navhelper" property="clientAppLinks" />
|
||||
</h3>
|
21
apps/routerconsole/jsp/netdb.jsp
Normal file
21
apps/routerconsole/jsp/netdb.jsp
Normal file
@@ -0,0 +1,21 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - network database summary</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.NetDbHelper" id="netdbHelper" scope="request" />
|
||||
<jsp:setProperty name="netdbHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
1
apps/routerconsole/jsp/notice.jsp
Normal file
1
apps/routerconsole/jsp/notice.jsp
Normal file
@@ -0,0 +1 @@
|
||||
<%=(null != request.getParameter("i2p.console.notice") ? request.getParameter("i2p.console.notice") : "")%>
|
21
apps/routerconsole/jsp/profiles.jsp
Normal file
21
apps/routerconsole/jsp/profiles.jsp
Normal file
@@ -0,0 +1,21 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<title>I2P Router Console - peer profiles</title>
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head><body>
|
||||
|
||||
<%@include file="nav.jsp" %>
|
||||
<%@include file="summary.jsp" %>
|
||||
<%@include file="notice.jsp" %>
|
||||
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:getProperty name="profilesHelper" property="profileSummary" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
40
apps/routerconsole/jsp/summary.jsp
Normal file
40
apps/routerconsole/jsp/summary.jsp
Normal file
@@ -0,0 +1,40 @@
|
||||
<%@page import="net.i2p.router.web.SummaryHelper" %>
|
||||
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
|
||||
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
|
||||
<div class="routersummary">
|
||||
<u><b>General</b></u><br />
|
||||
<b>Ident:</b> <jsp:getProperty name="helper" property="ident" /><br />
|
||||
<b>Version:</b> <jsp:getProperty name="helper" property="version" /><br />
|
||||
<b>Uptime:</b> <jsp:getProperty name="helper" property="uptime" /><br />
|
||||
<hr />
|
||||
|
||||
<u><b>Peers</b></u><br />
|
||||
<b>Active:</b> <jsp:getProperty name="helper" property="activePeers" /><br />
|
||||
<b>Fast:</b> <jsp:getProperty name="helper" property="fastPeers" /><br />
|
||||
<b>High capacity:</b> <jsp:getProperty name="helper" property="highCapacityPeers" /><br />
|
||||
<b>Well integrated:</b> <jsp:getProperty name="helper" property="wellIntegratedPeers" /><br />
|
||||
<b>Failing:</b> <jsp:getProperty name="helper" property="failingPeers" /><br />
|
||||
<b>Shitlisted:</b> <jsp:getProperty name="helper" property="shitlistedPeers" /><br />
|
||||
<hr />
|
||||
|
||||
<u><b>Bandwidth in/out</b></u><br />
|
||||
<b>1m:</b> <jsp:getProperty name="helper" property="inboundMinuteKBps" />/<jsp:getProperty name="helper" property="outboundMinuteKBps" />KBps<br />
|
||||
<b>5m:</b> <jsp:getProperty name="helper" property="inboundFiveMinuteKBps" />/<jsp:getProperty name="helper" property="outboundFiveMinuteKBps" />KBps<br />
|
||||
<b>Total:</b> <jsp:getProperty name="helper" property="inboundLifetimeKBps" />/<jsp:getProperty name="helper" property="outboundLifetimeKBps" />KBps<br />
|
||||
<b>Used:</b> <jsp:getProperty name="helper" property="inboundTransferred" />/<jsp:getProperty name="helper" property="outboundTransferred" /><br />
|
||||
<hr />
|
||||
|
||||
<u><b>Tunnels</b></u><br />
|
||||
<b>Inbound:</b> <jsp:getProperty name="helper" property="inboundTunnels" /><br />
|
||||
<b>Outbound:</b> <jsp:getProperty name="helper" property="outboundTunnels" /><br />
|
||||
<b>Participating:</b> <jsp:getProperty name="helper" property="participatingTunnels" /><br />
|
||||
<hr />
|
||||
|
||||
<u><b>Congestion</b></u><br />
|
||||
<b>Job lag:</b> <jsp:getProperty name="helper" property="jobLag" /><br />
|
||||
<b>Message delay:</b> <jsp:getProperty name="helper" property="messageDelay" /><br />
|
||||
<b>Tunnel lag:</b> <jsp:getProperty name="helper" property="tunnelLag" /><br />
|
||||
<hr />
|
||||
|
||||
</div>
|
17
apps/routerconsole/jsp/web.xml
Normal file
17
apps/routerconsole/jsp/web.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE web-app
|
||||
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
|
||||
"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
|
||||
|
||||
<web-app>
|
||||
<session-config>
|
||||
<session-timeout>
|
||||
30
|
||||
</session-timeout>
|
||||
</session-config>
|
||||
<welcome-file-list>
|
||||
<welcome-file>
|
||||
index.jsp
|
||||
</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
25
apps/routerconsole/readme.txt
Normal file
25
apps/routerconsole/readme.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
The routerconsole application is an embedable web server / servlet container.
|
||||
In it there is a bundled routerconsole.war containing JSPs (per jsp/*) that
|
||||
implement a web based control panel for the router. This console gives the user
|
||||
a quick view into how their router is operating and exposes some pages to
|
||||
configure it.
|
||||
|
||||
The web server itself is Jetty [1] and is contained within the various jar files
|
||||
under lib/. To embed this web server and the included router console, the
|
||||
startRouter script needs to be updated to include those jar files in the
|
||||
class path, plus the router.config needs appropriate entries to start up the
|
||||
server:
|
||||
|
||||
clientApp.3.main=net.i2p.router.web.RouterConsoleRunner
|
||||
clientApp.3.name=webConsole
|
||||
clientApp.3.args=7657 0.0.0.0 ./webapps/
|
||||
|
||||
That instructs the router to fire up the webserver listening on port 7657 on
|
||||
all of its interfaces (0.0.0.0), loading up any .war files under the ./webapps/
|
||||
directory. The RouterConsoleRunner itself configures the Jetty server to give
|
||||
the ./webapps/routerconsole.war control over the root context, directing a
|
||||
request to http://localhost:7657/index.jsp to the routerconsole.war's index.jsp.
|
||||
Any other .war file will be mounted under their filename's context (e.g.
|
||||
myi2p.war would be reachable at http://localhost:7657/myi2p/index.jsp).
|
||||
|
||||
[1] http://jetty.mortbay.com/jetty/index.html
|
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating system
|
||||
# Your operating environment
|
||||
#
|
||||
|
||||
OS = CYGWIN
|
||||
|
63
apps/sam/c/Makefile.freebsd
Normal file
63
apps/sam/c/Makefile.freebsd
Normal file
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# This Makefile is compatible with GNU Make (gmake) and should work on FreeBSD
|
||||
#
|
||||
|
||||
#
|
||||
# Your operating system
|
||||
#
|
||||
|
||||
OS = FREEBSD
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
|
||||
INCDIR = inc
|
||||
LIBDIR = lib
|
||||
OBJDIR = obj
|
||||
SRCDIR = src
|
||||
|
||||
#
|
||||
# Programs
|
||||
#
|
||||
|
||||
AR = ar
|
||||
CC = gcc
|
||||
|
||||
#
|
||||
# Flags
|
||||
#
|
||||
|
||||
CFLAGS = -g -O2 -pipe -std=c99 -Wall
|
||||
CFLAGS += -DOS=$(OS)
|
||||
CFLAGS += -I$(INCDIR)
|
||||
|
||||
#
|
||||
# Object files
|
||||
#
|
||||
|
||||
OBJS = $(OBJDIR)/sam.o
|
||||
|
||||
#
|
||||
# Build rules
|
||||
#
|
||||
|
||||
all: depend libsam
|
||||
|
||||
depend:
|
||||
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
libsam: $(OBJS)
|
||||
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
|
||||
|
||||
#
|
||||
# Cleanup rules
|
||||
#
|
||||
|
||||
clean:
|
||||
-rm -f $(LIBDIR)/libsam.a $(OBJDIR)/* .depend
|
||||
|
||||
tidy: clean
|
@@ -1,3 +1,12 @@
|
||||
v1.25
|
||||
* Rewrote sendq functions to automatically send big packets, for better
|
||||
network performance
|
||||
|
||||
v1.20 2004-07-11
|
||||
* Ported to FreeBSD (Makefile.freebsd)
|
||||
* Full winsock compatibility - all Windows functions now return appropriate
|
||||
error strings
|
||||
|
||||
v1.15 2004-06-23
|
||||
* Added a new example program, warhammer-dgram (use with caution)
|
||||
* Fixed some fatal bugs in datagram handling
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user