Browse Source

Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd

pull/451/head
Jeff Becker 8 years ago
parent
commit
64d7c87591
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 9
      ClientContext.cpp
  2. 6
      Config.cpp
  3. 65
      Daemon.cpp
  4. 2
      DaemonLinux.cpp
  5. 2
      DaemonWin32.cpp
  6. 262
      Log.cpp
  7. 272
      Log.h
  8. 46
      Queue.h
  9. 5
      Streaming.cpp
  10. 6
      api.cpp
  11. 2
      debian/i2pd.1
  12. 4
      debian/i2pd.links
  13. 20
      docs/configuration.md
  14. 30
      docs/family.md
  15. 141
      docs/i2pd.conf

9
ClientContext.cpp

@ -261,8 +261,15 @@ namespace client @@ -261,8 +261,15 @@ namespace client
{
boost::property_tree::ptree pt;
std::string tunConf; i2p::config::GetOption("tunconf", tunConf);
if (tunConf == "")
if (tunConf == "") {
// TODO: cleanup this in 2.8.0
tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
if (i2p::fs::Exists(tunConf)) {
LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
} else {
tunConf = i2p::fs::DataDirPath ("tunnels.conf");
}
}
LogPrint(eLogDebug, "FS: tunnels config file: ", tunConf);
try
{

6
Config.cpp

@ -107,10 +107,10 @@ namespace config { @@ -107,10 +107,10 @@ namespace config {
options_description general("General options");
general.add_options()
("help", "Show this message")
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)")
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg)")
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
("pidfile", value<std::string>()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)")
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file (stdout if not set, file - otherwise, for compatibility)")
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)")
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
("loglevel", value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")

65
Daemon.cpp

@ -69,27 +69,57 @@ namespace i2p @@ -69,27 +69,57 @@ namespace i2p
i2p::fs::Init();
datadir = i2p::fs::GetDataDir();
if (config == "")
// TODO: drop old name detection in v2.8.0
if (config == "")
{
config = i2p::fs::DataDirPath("i2p.conf");
// use i2p.conf only if exists
if (!i2p::fs::Exists (config)) config = ""; /* reset */
if (i2p::fs::Exists (config)) {
LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config);
} else {
config = i2p::fs::DataDirPath("i2pd.conf");
if (!i2p::fs::Exists (config)) {
// use i2pd.conf only if exists
config = ""; /* reset */
}
}
}
i2p::config::ParseConfig(config);
i2p::config::Finalize();
i2p::crypto::InitCrypto ();
i2p::context.Init ();
i2p::config::GetOption("daemon", isDaemon);
// TODO: move log init here
std::string logs = ""; i2p::config::GetOption("log", logs);
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
/* setup logging */
if (isDaemon && (logs == "" || logs == "stdout"))
logs = "file";
i2p::log::Logger().SetLogLevel(loglevel);
if (logs == "file") {
if (logfile == "")
logfile = i2p::fs::DataDirPath("i2pd.log");
LogPrint(eLogInfo, "Log: will send messages to ", logfile);
i2p::log::Logger().SendTo (logfile);
#ifndef _WIN32
} else if (logs == "syslog") {
LogPrint(eLogInfo, "Log: will send messages to syslog");
i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
#endif
} else {
// use stdout -- default
}
i2p::log::Logger().Ready();
LogPrint(eLogInfo, "i2pd v", VERSION, " starting");
LogPrint(eLogDebug, "FS: main config file: ", config);
LogPrint(eLogDebug, "FS: data directory: ", datadir);
i2p::crypto::InitCrypto ();
i2p::context.Init ();
uint16_t port; i2p::config::GetOption("port", port);
if (!i2p::config::IsDefault("port"))
{
@ -152,26 +182,6 @@ namespace i2p @@ -152,26 +182,6 @@ namespace i2p
bool Daemon_Singleton::start()
{
std::string logs = ""; i2p::config::GetOption("log", logs);
std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
if (isDaemon && (logs == "" || logs == "stdout"))
logs = "file";
if (logs == "syslog") {
// use syslog only no stdout
StartSyslog();
} else if (logs == "file") {
if (logfile == "")
logfile = i2p::fs::DataDirPath("i2pd.log");
StartLog (logfile);
} else {
// use stdout
StartLog ("");
}
SetLogLevel(loglevel);
bool http; i2p::config::GetOption("http.enabled", http);
if (http) {
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
@ -236,7 +246,6 @@ namespace i2p @@ -236,7 +246,6 @@ namespace i2p
d.m_I2PControlService = nullptr;
}
i2p::crypto::TerminateCrypto ();
StopLog ();
return true;
}

2
DaemonLinux.cpp

@ -19,7 +19,7 @@ void handle_signal(int sig) @@ -19,7 +19,7 @@ void handle_signal(int sig)
{
case SIGHUP:
LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log...");
ReopenLogFile ();
i2p::log::Logger().Reopen ();
break;
case SIGABRT:
case SIGTERM:

2
DaemonWin32.cpp

@ -75,7 +75,7 @@ namespace i2p @@ -75,7 +75,7 @@ namespace i2p
i2p::config::SetOption("log", std::string ("file"));
#endif
bool ret = Daemon_Singleton::start();
if (ret && IsLogToFile ())
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
{
// TODO: find out where this garbage to console comes from
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);

262
Log.cpp

@ -1,133 +1,167 @@ @@ -1,133 +1,167 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include "Log.h"
/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
Log * g_Log = nullptr;
#include "Log.h"
static const char * g_LogLevelStr[eNumLogLevels] =
{
"error", // eLogError
"warn", // eLogWarning
"info", // eLogInfo
"debug" // eLogDebug
};
#ifndef _WIN32
/** convert LogLevel enum to syslog priority level */
static int ToSyslogLevel(LogLevel lvl)
{
switch (lvl) {
case eLogError:
return LOG_ERR;
case eLogWarning:
return LOG_WARNING;
case eLogInfo:
return LOG_INFO;
case eLogDebug:
return LOG_DEBUG;
default:
// WTF? invalid log level?
return LOG_CRIT;
}
}
#endif
namespace i2p {
namespace log {
Log logger;
/**
* @enum Maps our loglevel to their symbolic name
*/
static const char * g_LogLevelStr[eNumLogLevels] =
{
"error", // eLogError
"warn", // eLogWarn
"info", // eLogInfo
"debug" // eLogDebug
};
void LogMsg::Process()
{
#ifndef _WIN32
if (log && log->SyslogEnabled()) {
// only log to syslog
syslog(ToSyslogLevel(level), "%s", s.str().c_str());
return;
}
/**
* @brief Maps our log levels to syslog one
* @return syslog priority LOG_*, as defined in syslog.h
*/
static inline int GetSyslogPrio (enum LogLevel l) {
int priority = LOG_DEBUG;
switch (l) {
case eLogError : priority = LOG_ERR; break;
case eLogWarning : priority = LOG_WARNING; break;
case eLogInfo : priority = LOG_INFO; break;
case eLogDebug : priority = LOG_DEBUG; break;
default : priority = LOG_DEBUG; break;
}
return priority;
}
#endif
auto stream = log ? log->GetLogStream () : nullptr;
auto& output = stream ? *stream : std::cout;
if (log)
output << log->GetTimestamp ();
else
output << boost::posix_time::second_clock::local_time().time_of_day ();
output << "/" << g_LogLevelStr[level] << " - ";
output << s.str();
}
const std::string& Log::GetTimestamp ()
{
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) && !defined(__clang__)
auto ts = std::chrono::monotonic_clock::now ();
#else
auto ts = std::chrono::steady_clock::now ();
#endif
if (ts > m_LastTimestampUpdate + std::chrono::milliseconds (500)) // 0.5 second
Log::Log():
m_Destination(eLogStdout), m_MinLevel(eLogInfo),
m_LogStream (nullptr), m_Logfile(""), m_IsReady(false)
{
m_LastTimestampUpdate = ts;
m_Timestamp = boost::posix_time::to_simple_string (boost::posix_time::second_clock::local_time().time_of_day ());
}
return m_Timestamp;
}
void Log::Flush ()
{
if (m_LogStream)
m_LogStream->flush();
}
}
void Log::SetLogFile (const std::string& fullFilePath, bool truncate)
{
m_FullFilePath = fullFilePath;
auto mode = std::ofstream::out | std::ofstream::binary;
mode |= truncate ? std::ofstream::trunc : std::ofstream::app;
auto logFile = std::make_shared<std::ofstream> (fullFilePath, mode);
if (logFile->is_open ())
Log::~Log ()
{
SetLogStream (logFile);
LogPrint(eLogInfo, "Log: will send messages to ", fullFilePath);
}
}
switch (m_Destination) {
#ifndef _WIN32
case eLogSyslog :
closelog();
break;
#endif
case eLogFile:
case eLogStream:
m_LogStream->flush();
break;
default:
/* do nothing */
break;
}
Process();
}
void Log::ReopenLogFile ()
{
if (m_FullFilePath.length () > 0)
{
SetLogFile (m_FullFilePath, false); // don't truncate
LogPrint(eLogInfo, "Log: file ", m_FullFilePath, " reopen");
void Log::SetLogLevel (const std::string& level) {
if (level == "error") { m_MinLevel = eLogError; }
else if (level == "warn") { m_MinLevel = eLogWarning; }
else if (level == "info") { m_MinLevel = eLogInfo; }
else if (level == "debug") { m_MinLevel = eLogDebug; }
else {
LogPrint(eLogError, "Log: unknown loglevel: ", level);
return;
}
LogPrint(eLogInfo, "Log: min messages level set to ", level);
}
const char * Log::TimeAsString(std::time_t t) {
if (t != m_LastTimestamp) {
strftime(m_LastDateTime, sizeof(m_LastDateTime), "%H:%M:%S", localtime(&t));
m_LastTimestamp = t;
}
return m_LastDateTime;
}
}
/**
* @note This function better to be run in separate thread due to disk i/o.
* Unfortunately, with current startup process with late fork() this
* will give us nothing but pain. Maybe later. See in NetDb as example.
*/
void Log::Process() {
std::unique_lock<std::mutex> l(m_OutputLock);
std::hash<std::thread::id> hasher;
unsigned short short_tid;
while (1) {
auto msg = m_Queue.GetNextWithTimeout (1);
if (!msg)
break;
short_tid = (short) (hasher(msg->tid) % 1000);
switch (m_Destination) {
#ifndef _WIN32
case eLogSyslog:
syslog(GetSyslogPrio(msg->level), "[%03u] %s", short_tid, msg->text.c_str());
break;
#endif
case eLogFile:
case eLogStream:
*m_LogStream << TimeAsString(msg->timestamp)
<< "@" << short_tid
<< "/" << g_LogLevelStr[msg->level]
<< " - " << msg->text << std::endl;
break;
case eLogStdout:
default:
std::cout << TimeAsString(msg->timestamp)
<< "@" << short_tid
<< "/" << g_LogLevelStr[msg->level]
<< " - " << msg->text << std::endl;
break;
} // switch
} // while
}
void Log::SetLogLevel (const std::string& level)
{
if (level == "error") { m_MinLevel = eLogError; }
else if (level == "warn") { m_MinLevel = eLogWarning; }
else if (level == "info") { m_MinLevel = eLogInfo; }
else if (level == "debug") { m_MinLevel = eLogDebug; }
else {
LogPrint(eLogError, "Log: Unknown loglevel: ", level);
return;
}
LogPrint(eLogInfo, "Log: min msg level set to ", level);
}
void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg) {
m_Queue.Put(msg);
if (!m_IsReady)
return;
Process();
}
void Log::SetLogStream (std::shared_ptr<std::ostream> logStream)
{
m_LogStream = logStream;
}
void Log::SendTo (const std::string& path) {
auto flags = std::ofstream::out | std::ofstream::app;
auto os = std::make_shared<std::ofstream> (path, flags);
if (os->is_open ()) {
m_Logfile = path;
m_Destination = eLogFile;
m_LogStream = os;
return;
}
LogPrint(eLogError, "Log: can't open file ", path);
}
void Log::StartSyslog(const std::string & ident, const int facility)
{
#ifndef _WIN32
m_Ident = ident;
openlog(m_Ident.c_str(), LOG_PID, facility);
#endif
}
void Log::SendTo (std::shared_ptr<std::ostream> os) {
m_Destination = eLogStream;
m_LogStream = os;
}
void Log::StopSyslog()
{
#ifndef _WIN32
closelog();
m_Ident.clear();
void Log::SendTo(const char *name, int facility) {
m_Destination = eLogSyslog;
m_LogStream = nullptr;
openlog(name, LOG_CONS | LOG_PID, facility);
}
#endif
}
bool Log::SyslogEnabled()
{
return m_Ident.size() > 0;
}
void Log::Reopen() {
if (m_Destination == eLogFile)
SendTo(m_Logfile);
}
Log & Logger() {
return logger;
}
} // log
} // i2p

272
Log.h

@ -1,11 +1,19 @@ @@ -1,11 +1,19 @@
/*
* Copyright (c) 2013-2016, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef LOG_H__
#define LOG_H__
#include <ctime>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <functional>
#include <sstream>
#include <chrono>
#include <memory>
#include "Queue.h"
@ -23,150 +31,156 @@ enum LogLevel @@ -23,150 +31,156 @@ enum LogLevel
eNumLogLevels
};
class Log;
struct LogMsg
{
std::stringstream s;
Log * log;
LogLevel level;
LogMsg (Log * l = nullptr, LogLevel lv = eLogInfo): log (l), level (lv) {};
void Process();
};
class Log: public i2p::util::MsgQueue<LogMsg>
{
public:
Log () { SetOnEmpty (std::bind (&Log::Flush, this)); };
~Log () {};
void SetLogFile (const std::string& fullFilePath, bool truncate = true);
void ReopenLogFile ();
void SetLogLevel (const std::string& level);
void SetLogStream (std::shared_ptr<std::ostream> logStream);
std::shared_ptr<std::ostream> GetLogStream () const { return m_LogStream; };
const std::string& GetTimestamp ();
LogLevel GetLogLevel () { return m_MinLevel; };
const std::string& GetFullFilePath () const { return m_FullFilePath; };
/** start logging to syslog */
void StartSyslog(const std::string & ident, const int facility);
/** stop logging to syslog */
void StopSyslog();
/** are we logging to syslog right now? */
bool SyslogEnabled();
private:
void Flush ();
private:
std::string m_FullFilePath; // empty if stream
std::shared_ptr<std::ostream> m_LogStream;
enum LogLevel m_MinLevel;
std::string m_Timestamp;
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) && !defined(__clang__) // gcc 4.6
std::chrono::monotonic_clock::time_point m_LastTimestampUpdate;
#else
std::chrono::steady_clock::time_point m_LastTimestampUpdate;
enum LogType {
eLogStdout = 0,
eLogStream,
eLogFile,
#ifndef _WIN32
eLogSyslog,
#endif
std::string m_Ident;
};
extern Log * g_Log;
namespace i2p {
namespace log {
struct LogMsg; /* forward declaration */
inline void StartLog (const std::string& fullFilePath)
{
if (!g_Log)
{
auto log = new Log ();
if (fullFilePath.length () > 0)
log->SetLogFile (fullFilePath);
g_Log = log;
}
}
inline void StartLog (std::shared_ptr<std::ostream> s)
{
if (!g_Log)
{
auto log = new Log ();
if (s)
log->SetLogStream (s);
g_Log = log;
}
}
inline void StopLog ()
{
if (g_Log)
class Log
{
auto log = g_Log;
g_Log = nullptr;
log->Stop ();
delete log;
}
}
inline void SetLogLevel (const std::string& level)
{
if (g_Log)
g_Log->SetLogLevel(level);
}
inline void ReopenLogFile ()
{
if (g_Log)
g_Log->ReopenLogFile ();
}
inline bool IsLogToFile ()
{
return g_Log ? !g_Log->GetFullFilePath ().empty () : false;
}
inline void StartSyslog()
{
StartLog("");
#ifndef _WIN32
g_Log->StartSyslog("i2pd", LOG_USER);
#endif
}
inline void StopSyslog()
{
if(g_Log)
g_Log->StopSyslog();
}
private:
enum LogType m_Destination;
enum LogLevel m_MinLevel;
std::shared_ptr<std::ostream> m_LogStream;
std::string m_Logfile;
std::time_t m_LastTimestamp;
char m_LastDateTime[64];
i2p::util::Queue<std::shared_ptr<LogMsg> > m_Queue;
volatile bool m_IsReady;
mutable std::mutex m_OutputLock;
private:
/** prevent making copies */
Log (const Log &);
const Log& operator=(const Log&);
/**
* @brief process stored messages in queue
*/
void Process ();
/**
* @brief Makes formatted string from unix timestamp
* @param ts Second since epoch
*
* This function internally caches the result for last provided value
*/
const char * TimeAsString(std::time_t ts);
public:
Log ();
~Log ();
LogType GetLogType () { return m_Destination; };
LogLevel GetLogLevel () { return m_MinLevel; };
/**
* @brief Sets minimal alloed level for log messages
* @param level String with wanted minimal msg level
*/
void SetLogLevel (const std::string& level);
/**
* @brief Sets log destination to logfile
* @param path Path to logfile
*/
void SendTo (const std::string &path);
/**
* @brief Sets log destination to given output stream
* @param os Output stream
*/
void SendTo (std::shared_ptr<std::ostream> s);
#ifndef _WIN32
/**
* @brief Sets log destination to syslog
* @param name Wanted program name
* @param facility Wanted log category
*/
void SendTo (const char *name, int facility);
#endif
/**
* @brief Format log message and write to output stream/syslog
* @param msg Pointer to processed message
*/
void Append(std::shared_ptr<i2p::log::LogMsg> &);
/** @brief Allow log output */
void Ready() { m_IsReady = true; }
/** @brief Flushes the output log stream */
void Flush();
/** @brief Reopen log file */
void Reopen();
};
/**
* @struct Log message container
*
* We creating it somewhere with LogPrint(),
* then put in MsgQueue for later processing.
*/
struct LogMsg {
std::time_t timestamp;
std::string text; /**< message text as single string */
LogLevel level; /**< message level */
std::thread::id tid; /**< id of thread that generated message */
LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl), tid(0) {};
};
Log & Logger();
} // log
} // i2p
/** internal usage only -- folding args array to single string */
template<typename TValue>
void LogPrint (std::stringstream& s, TValue arg)
void LogPrint (std::stringstream& s, TValue arg)
{
s << arg;
}
/** internal usage only -- folding args array to single string */
template<typename TValue, typename... TArgs>
void LogPrint (std::stringstream& s, TValue arg, TArgs... args)
void LogPrint (std::stringstream& s, TValue arg, TArgs... args)
{
LogPrint (s, arg);
LogPrint (s, args...);
}
/**
* @brief Create log message and send it to queue
* @param level Message level (eLogError, eLogInfo, ...)
* @param args Array of message parts
*/
template<typename... TArgs>
void LogPrint (LogLevel level, TArgs... args)
void LogPrint (LogLevel level, TArgs... args)
{
if (g_Log && level > g_Log->GetLogLevel ())
i2p::log::Log &log = i2p::log::Logger();
if (level > log.GetLogLevel ())
return;
LogMsg * msg = new LogMsg (g_Log, level);
LogPrint (msg->s, args...);
msg->s << std::endl;
if (g_Log) {
g_Log->Put (msg);
} else {
msg->Process ();
delete msg;
}
// fold message to single string
std::stringstream ss("");
LogPrint (ss, args ...);
auto msg = std::make_shared<i2p::log::LogMsg>(level, std::time(nullptr), ss.str());
msg->tid = std::this_thread::get_id();
log.Append(msg);
}
#endif
#endif // LOG_H__

46
Queue.h

@ -117,52 +117,6 @@ namespace util @@ -117,52 +117,6 @@ namespace util
std::mutex m_QueueMutex;
std::condition_variable m_NonEmpty;
};
template<class Msg>
class MsgQueue: public Queue<Msg *>
{
public:
typedef std::function<void()> OnEmpty;
MsgQueue (): m_IsRunning (true), m_Thread (std::bind (&MsgQueue<Msg>::Run, this)) {};
~MsgQueue () { Stop (); };
void Stop()
{
if (m_IsRunning)
{
m_IsRunning = false;
Queue<Msg *>::WakeUp ();
m_Thread.join();
}
}
void SetOnEmpty (OnEmpty const & e) { m_OnEmpty = e; };
private:
void Run ()
{
while (m_IsRunning)
{
while (auto msg = Queue<Msg *>::Get ())
{
msg->Process ();
delete msg;
}
if (m_OnEmpty != nullptr)
m_OnEmpty ();
if (m_IsRunning)
Queue<Msg *>::Wait ();
}
}
private:
volatile bool m_IsRunning;
OnEmpty m_OnEmpty;
std::thread m_Thread;
};
}
}

5
Streaming.cpp

@ -162,9 +162,8 @@ namespace stream @@ -162,9 +162,8 @@ namespace stream
void Stream::SavePacket (Packet * packet)
{
auto ins = m_SavedPackets.insert (packet);
// delete packed if not saved
if (!ins.second) delete packet;
if (!m_SavedPackets.insert (packet).second)
delete packet;
}
void Stream::ProcessPacket (Packet * packet)

6
api.cpp

@ -40,9 +40,10 @@ namespace api @@ -40,9 +40,10 @@ namespace api
void StartI2P (std::shared_ptr<std::ostream> logStream)
{
if (logStream)
StartLog (logStream);
i2p::log::Logger().SendTo (logStream);
else
StartLog (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
i2p::log::Logger().SendTo (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
i2p::log::Logger().Ready();
LogPrint(eLogInfo, "API: starting NetDB");
i2p::data::netdb.Start();
LogPrint(eLogInfo, "API: starting Transports");
@ -60,7 +61,6 @@ namespace api @@ -60,7 +61,6 @@ namespace api
i2p::transport::transports.Stop();
LogPrint(eLogInfo, "API: stopping NetDB");
i2p::data::netdb.Stop();
StopLog ();
}
void RunPeerTest ()

2
debian/i2pd.1 vendored

@ -68,7 +68,7 @@ Port of BOB command channel. Usually \fI2827\fR. BOB will not be enabled if this @@ -68,7 +68,7 @@ Port of BOB command channel. Usually \fI2827\fR. BOB will not be enabled if this
Port of I2P control service. Usually \fI7650\fR. I2PControl will not be enabled if this is not set. (default: unset)
.TP
\fB\-\-conf=\fR
Config file (default: \fI~/.i2pd/i2p.conf\fR or \fI/var/lib/i2pd/i2p.conf\fR)
Config file (default: \fI~/.i2pd/i2pd.conf\fR or \fI/var/lib/i2pd/i2pd.conf\fR)
This parameter will be silently ignored if the specified config file does not exist.
Options specified on the command line take precedence over those in the config file.

4
debian/i2pd.links vendored

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
etc/i2pd/i2pd.conf var/lib/i2pd/i2p.conf
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.cfg
etc/i2pd/i2pd.conf var/lib/i2pd/i2pd.conf
etc/i2pd/tunnels.conf var/lib/i2pd/tunnels.conf
etc/i2pd/subscriptions.txt var/lib/i2pd/subscriptions.txt
usr/share/i2pd/certificates var/lib/i2pd/certificates

20
docs/configuration.md

@ -4,10 +4,13 @@ i2pd configuration @@ -4,10 +4,13 @@ i2pd configuration
Command line options
--------------------
* --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)
Options specified on the command line take precedence over those in the config file.
If you are upgrading your very old router (< 2.3.0) see also [this](config_opts_after_2.3.0.md) page.
* --help - Show builtin help message (default value of option will be shown in braces)
* --conf= - Config file (default: ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)
This parameter will be silently ignored if the specified config file does not exist.
Options specified on the command line take precedence over those in the config file.
* --tunconf= - Tunnels config file (default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg)
* --tunconf= - Tunnels config file (default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)
* --pidfile= - Where to write pidfile (dont write by default)
* --log= - Logs destination: stdout, file (stdout if not set, file - otherwise, for compatibility)
* --logfile= - Path to logfile (default - autodetect)
@ -24,6 +27,8 @@ Command line options @@ -24,6 +27,8 @@ Command line options
* --family= - Name of a family, router belongs to
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
All options below still possible in cmdline, but better write it in config file:
* --http.address= - The address to listen on (HTTP server)
* --http.port= - The port to listen on (HTTP server)
@ -60,7 +65,7 @@ All command-line parameters are allowed as keys, but note for those which contai @@ -60,7 +65,7 @@ All command-line parameters are allowed as keys, but note for those which contai
For example:
i2p.conf:
i2pd.conf:
# comment
log = true
@ -69,11 +74,13 @@ i2p.conf: @@ -69,11 +74,13 @@ i2p.conf:
[httpproxy]
port = 4444
# ^^ this will be --httproxy.port= in cmdline
# another one
# another comment
[sam]
enabled = true
tunnels.cfg (filename of this config is subject of change):
See also commented config with examples of all options in ``docs/i2pd.conf``.
tunnels.conf:
# outgoing tunnel sample, to remote service
# mandatory parameters:
@ -107,6 +114,7 @@ tunnels.cfg (filename of this config is subject of change): @@ -107,6 +114,7 @@ tunnels.cfg (filename of this config is subject of change):
host = 127.0.0.1
port = 80
keys = site-keys.dat
#
[IRC-SERVER]
type = server
host = 127.0.0.1

30
docs/family.md

@ -6,27 +6,31 @@ There are two possibilities: create new family or joing to existing. @@ -6,27 +6,31 @@ There are two possibilities: create new family or joing to existing.
New family
-----------
You must create family self-signed certificate and key.
The only key type supposted is prime256v1.
Use the following list of commands:
openssl ecparam -name prime256v1 -genkey -out <your family name>.key
openssl req -new -key <your family name>.key -out <your family name>.csr
touch v3.ext
openssl x509 -req -days 3650 -in <your family name>.csr -signkey <your family name>.key -out <your family name>.crt -extfile v3.ext
specify <your family name>.family.i2p.net for CN.
openssl ecparam -name prime256v1 -genkey -out <your family name>.key
openssl req -new -key <your family name>.key -out <your family name>.csr
touch v3.ext
openssl x509 -req -days 3650 -in <your family name>.csr -signkey <your family name>.key -out <your family name>.crt -extfile v3.ext
Specify <your family name>.family.i2p.net for CN (Common Name) when requested.
Once you are done with it place <your family name>.key and <your family name>.crt to <ip2d data>/family folder (for exmple ~/.i2pd/family).
Once you are done with it place <your-family-name>.key and <your-family-name>.crt to <ip2d data>/family folder (for exmple ~/.i2pd/family).
You should provide these two files to other members joining your family.
If you want to register you family and let I2P network recorgnize it, create pull request for you .crt file into contrib/certificate/family.
It will appear in i2pd and I2P next releases packages. Don't place .key file, it must be shared betwwen you family members only.
It will appear in i2pd and I2P next releases packages. Dont place .key file, it must be shared between you family members only.
How to join existing family
---------------------------
Join existing family
--------------------
Once you and that family agree to do it, they must give you .key and .crt file and you must place to <ip2d data>/family folder.
Once you and that family agree to do it, they must give you .key and .crt file and you must place in <i2pd datadir>/certificates/family/ folder.
Publish your family
------------------
Run i2pd with parameter 'family=<your family name>', make sure you have <your family name>.key and <your family name>.crt in your 'family' folder.
If everything is set properly, you router.info will contain two new fields: 'family' and 'family.sig'.
-------------------
Run i2pd with parameter 'family=<your-family-name>', make sure you have <your-family-name>.key and <your-family-name>.crt in your 'family' folder.
If everything is set properly, you router.info will contain two new fields: 'family' and 'family.sig'.
Otherwise your router will complain on startup with log messages starting with "Family:" prefix and severity 'warn' or 'error'.

141
docs/i2pd.conf

@ -6,109 +6,104 @@ @@ -6,109 +6,104 @@
## that begin with just "#" are disabled commands: you can enable them
## by removing the "#" symbol.
## Tunnels config file
## Default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg
#tunconf = /var/lib/i2pd/tunnels.cfg
## Tunnels config file
## Default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf
# tunconf = /var/lib/i2pd/tunnels.conf
## Where to write pidfile (don't write by default)
#pidfile = /var/run/i2pd.pid
# pidfile = /var/run/i2pd.pid
## Logging configuration section
## By default logs go to stdout with level info
## By default logs go to stdout with level 'info' and higher
##
## Logs destination (stdout, file, syslog)
## stdout - print log entries to stdout
## file - log entries to a file
## syslog - use syslog, see man 3 syslog
#log = file
## Logs destination (valid values: stdout, file, syslog)
## * stdout - print log entries to stdout
## * file - log entries to a file
## * syslog - use syslog, see man 3 syslog
# log = file
## Path to logfile (default - autodetect)
#logfile = /var/log/i2pd.log
# logfile = /var/log/i2pd.log
## Log messages above this level (debug, *info, warn, error)
#loglevel = info
# loglevel = info
## Path to storage of i2pd data (RI, keys, peer profiles, ...)
## Default: ~/.i2pd or /var/lib/i2pd
#datadir = /var/lib/i2pd
# datadir = /var/lib/i2pd
## Daemon mode. Router will go to background after start
#daemon
# daemon = true
## Run as a service. Router will use system folders like ‘/var/lib/i2pd’
#service
# service = true
## External IP address to listen for connections
## By default i2pd sets IP automatically
#host = 1.2.3.4
# host = 1.2.3.4
## Port to listen for connections
## By default i2pd picks random port. You MUST pick a random number too,
## By default i2pd picks random port. You MUST pick a random number too,
## don't just uncomment this
#port = 4321
##Enable communication through ipv6
# port = 4321
## Enable communication through ipv6
ipv6 = true
## Bandwidth configuration
## L limit bandwidth to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
## Default is P for floodfill, L for regular node
#bandwidth = L
# bandwidth = L
## Router will not accept transit tunnels at startup
#notransit
# notransit = true
## Router will be floodfill
#floodfill
# floodfill = true
## Section for Web Console
## By default it's available at 127.0.0.1:7070 even if it's not configured
[http]
## The address to listen on
address = 127.0.0.1
## The port to listen on
port = 7070
## Uncomment and set to 'false' to disable Web Console
# enabled = true
## Address and port service will listen on
address = 127.0.0.1
port = 7070
## Section for HTTP proxy
## By default it's available at 127.0.0.1:4444 even if it's not configured
[httpproxy]
## The address to listen on
address = 127.0.0.1
## The port to listen on
port = 4444
## Uncomment and set to 'false' to disable HTTP Proxy
# enabled = true
## Address and port service will listen on
# address = 127.0.0.1
# port = 4444
## Optional keys file for proxy local destination
#keys = http-proxy-keys.dat
## Uncomment if you want to disable HTTP proxy
#enabled=false
## Section for Socks proxy
## By default it's available at 127.0.0.1:4447 even if it's not configured
#[socksproxy]
## The address to listen on
#address = 127.0.0.1
## The port to listen on
#port = 4447
# keys = http-proxy-keys.dat
[socksproxy]
## Uncomment and set to 'false' to disable SOCKS Proxy
# enabled = true
## Address and port service will listen on
# address = 127.0.0.1
# port = 4447
## Optional keys file for proxy local destination
#keys = socks-proxy-keys.dat
## Uncomment if you want to disable Socks proxy
#enabled=false
# keys = socks-proxy-keys.dat
## Socks outproxy. Example below is set to use Tor for all connections except i2p
## Address of outproxy
#outproxy = 127.0.0.1
## Outproxy remote port
#outproxyport = 9050
## Section for SAM bridge
#[sam]
## The address to listen on
#address = 127.0.0.1
## Port of SAM bridge
#port = 7656
## Section for BOB command channel
#[bob]
## The address to listen on
#address = 127.0.0.1
## Port of BOB command channel. Usually 2827. BOB is off if not specified
#port = 2827
## Section for I2PControl protocol
#[i2pcontrol]
## The address to listen on
#address = 127.0.0.1
## Port of I2P control service
#port = 7650
## Address and port of outproxy
# outproxy = 127.0.0.1
# outproxyport = 9050
[sam]
## Uncomment and set to 'true' to enable SAM Bridge
# enabled = false
## Address and port service will listen on
# address = 127.0.0.1
# port = 7656
[bob]
## Uncomment and set to 'true' to enable BOB command channel
# enabled = false
## Address and port service will listen on
# address = 127.0.0.1
# port = 2827
[i2pcontrol]
## Uncomment and set to 'true' to enable I2PControl protocol
# enabled = false
## Address and port service will listen on
# address = 127.0.0.1
# port = 7650

Loading…
Cancel
Save