mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
Merge pull request #1971 from sehraf/pr_i2p_refactoring
i2p refactoring
This commit is contained in:
commit
891d7e7c9a
@ -154,6 +154,7 @@ rs_webui {
|
||||
HEADERS += plugins/pluginmanager.h \
|
||||
plugins/dlfcn_win32.h \
|
||||
rsitems/rspluginitems.h \
|
||||
util/i2pcommon.h \
|
||||
util/rsinitedptr.h
|
||||
|
||||
HEADERS += $$PUBLIC_HEADERS
|
||||
@ -517,7 +518,8 @@ SOURCES += ft/ftchunkmap.cc \
|
||||
ft/ftfilesearch.cc \
|
||||
ft/ftserver.cc \
|
||||
ft/fttransfermodule.cc \
|
||||
ft/ftturtlefiletransferitem.cc
|
||||
ft/ftturtlefiletransferitem.cc \
|
||||
util/i2pcommon.cpp
|
||||
|
||||
SOURCES += crypto/chacha20.cpp \
|
||||
crypto/hashstream.cc\
|
||||
|
@ -161,7 +161,9 @@ public:
|
||||
p3ChatService *chatSrv;
|
||||
p3StatusService *mStatusSrv;
|
||||
p3GxsTunnelService *mGxsTunnels;
|
||||
#ifdef RS_USE_I2P_BOB
|
||||
p3I2pBob *mI2pBob;
|
||||
#endif
|
||||
|
||||
// This list contains all threaded services. It will be used to shut them down properly.
|
||||
|
||||
|
@ -923,8 +923,10 @@ int RsServer::StartupRetroShare()
|
||||
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
|
||||
|
||||
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
|
||||
#ifdef RS_USE_I2P_BOB
|
||||
mI2pBob = new p3I2pBob(mPeerMgr);
|
||||
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
|
||||
#endif
|
||||
|
||||
//load all the SSL certs as friends
|
||||
// std::list<std::string> sslIds;
|
||||
@ -1649,7 +1651,9 @@ int RsServer::StartupRetroShare()
|
||||
mConfigMgr->addConfiguration("wire.cfg", wire_ns);
|
||||
#endif
|
||||
#endif //RS_ENABLE_GXS
|
||||
#ifdef RS_USE_I2P_BOB
|
||||
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
|
||||
#endif
|
||||
|
||||
mPluginsManager->addConfigurations(mConfigMgr) ;
|
||||
|
||||
@ -1724,7 +1728,7 @@ int RsServer::StartupRetroShare()
|
||||
// now enable bob
|
||||
bobSettings bs;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
|
||||
bs.enableBob = true;
|
||||
bs.enable = true;
|
||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
|
||||
} else {
|
||||
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
|
||||
@ -1795,7 +1799,9 @@ int RsServer::StartupRetroShare()
|
||||
/**************************************************************************/
|
||||
|
||||
// auto proxy threads
|
||||
#ifdef RS_USE_I2P_BOB
|
||||
startServiceThread(mI2pBob, "I2P-BOB");
|
||||
#endif
|
||||
|
||||
#ifdef RS_ENABLE_GXS
|
||||
// Must Set the GXS pointers before starting threads.
|
||||
|
@ -43,21 +43,14 @@ static const std::string kConfigKeyOutLength = "OUT_LENGTH";
|
||||
static const std::string kConfigKeyOutQuantity = "OUT_QUANTITY";
|
||||
static const std::string kConfigKeyOutVariance = "OUT_VARIANCE";
|
||||
|
||||
static const bool kDefaultBOBEnable = false;
|
||||
static const int8_t kDefaultLength = 3;
|
||||
static const int8_t kDefaultQuantity = 4;
|
||||
static const int8_t kDefaultVariance = 0;
|
||||
|
||||
/// Sleep duration for receiving loop
|
||||
static const useconds_t sleepTimeRecv = 10; // times 1000 = 10ms
|
||||
/// Sleep duration for receiving loop in error/no-data case
|
||||
static const useconds_t sleepTimeRecv = 250; // times 1000 = 250ms
|
||||
/// Sleep duration for everything else
|
||||
static const useconds_t sleepTimeWait = 50; // times 1000 = 50ms or 0.05s
|
||||
static const int sleepFactorDefault = 10; // 0.5s
|
||||
static const int sleepFactorFast = 1; // 0.05s
|
||||
static const int sleepFactorSlow = 20; // 1s
|
||||
|
||||
static struct RsLog::logInfo i2pBobLogInfo = {RsLog::Default, "p3I2pBob"};
|
||||
|
||||
static const rstime_t selfCheckPeroid = 30;
|
||||
|
||||
void doSleep(useconds_t timeToSleepMS) {
|
||||
@ -74,15 +67,7 @@ p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr)
|
||||
mProcessing(NULL), mLock("I2P-BOB")
|
||||
{
|
||||
// set defaults
|
||||
mSetting.enableBob = kDefaultBOBEnable;
|
||||
mSetting.keys = "";
|
||||
mSetting.addr = "";
|
||||
mSetting.inLength = kDefaultLength;
|
||||
mSetting.inQuantity = kDefaultQuantity;
|
||||
mSetting.inVariance = kDefaultVariance;
|
||||
mSetting.outLength = kDefaultLength;
|
||||
mSetting.outQuantity = kDefaultQuantity;
|
||||
mSetting.outVariance = kDefaultVariance;
|
||||
mSetting.initDefault();
|
||||
|
||||
mCommands.clear();
|
||||
}
|
||||
@ -90,12 +75,12 @@ p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr)
|
||||
bool p3I2pBob::isEnabled()
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
return mSetting.enableBob;
|
||||
return mSetting.enable;
|
||||
}
|
||||
|
||||
bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||
{
|
||||
std::cout << "p3I2pBob::initialSetup" << std::endl;
|
||||
RS_DBG("");
|
||||
|
||||
// update config
|
||||
{
|
||||
@ -108,7 +93,7 @@ bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup config updated" << std::endl;
|
||||
RS_DBG("config updated");
|
||||
|
||||
// request keys
|
||||
// p3I2pBob::stateMachineBOB expects mProcessing to be set therefore
|
||||
@ -118,12 +103,12 @@ bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||
fakeTicket->task = autoProxyTask::receiveKey;
|
||||
processTaskAsync(fakeTicket);
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup fakeTicket requested" << std::endl;
|
||||
RS_DBG("fakeTicket requested");
|
||||
|
||||
// now start thread
|
||||
start("I2P-BOB gen key");
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup thread started" << std::endl;
|
||||
RS_DBG("thread started");
|
||||
|
||||
int counter = 0;
|
||||
// wait for keys
|
||||
@ -137,24 +122,24 @@ bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||
break;
|
||||
|
||||
if (++counter > 30) {
|
||||
std::cout << "p3I2pBob::initialSetup timeout!" << std::endl;
|
||||
RS_DBG4("timeout!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup got keys" << std::endl;
|
||||
RS_DBG("got keys");
|
||||
|
||||
// stop thread
|
||||
fullstop();
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup thread stopped" << std::endl;
|
||||
RS_DBG("thread stopped");
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
addr = mSetting.addr;
|
||||
addr = mSetting.address.base32;
|
||||
}
|
||||
|
||||
std::cout << "p3I2pBob::initialSetup addr '" << addr << "'" << std::endl;
|
||||
RS_DBG4("addr ", addr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -172,7 +157,7 @@ void p3I2pBob::processTaskAsync(taskTicket *ticket)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::processTaskAsync unknown task");
|
||||
RS_DBG("unknown task");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
break;
|
||||
}
|
||||
@ -187,7 +172,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||
case autoProxyTask::status:
|
||||
// check if everything needed is set
|
||||
if (!data) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::status autoProxyTask::status data is missing");
|
||||
RS_DBG("autoProxyTask::status data is missing");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
break;
|
||||
}
|
||||
@ -201,7 +186,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||
case autoProxyTask::getSettings:
|
||||
// check if everything needed is set
|
||||
if (!data) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::getSettings data is missing");
|
||||
RS_DBG("autoProxyTask::getSettings data is missing");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
break;
|
||||
}
|
||||
@ -215,7 +200,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||
case autoProxyTask::setSettings:
|
||||
// check if everything needed is set
|
||||
if (!data) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::setSettings data is missing");
|
||||
RS_DBG("autoProxyTask::setSettings data is missing");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
break;
|
||||
}
|
||||
@ -235,7 +220,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||
break;
|
||||
case autoProxyTask::getErrorInfo:
|
||||
if (!data) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::getErrorInfo data is missing");
|
||||
RS_DBG("autoProxyTask::getErrorInfo data is missing");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
} else {
|
||||
RS_STACK_MUTEX(mLock);
|
||||
@ -244,34 +229,12 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::processTaskSync unknown task");
|
||||
RS_DBG("unknown task");
|
||||
rsAutoProxyMonitor::taskError(ticket);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string p3I2pBob::keyToBase32Addr(const std::string &key)
|
||||
{
|
||||
std::string copy(key);
|
||||
|
||||
// replace I2P specific chars
|
||||
std::replace(copy.begin(), copy.end(), '~', '/');
|
||||
std::replace(copy.begin(), copy.end(), '-', '+');
|
||||
|
||||
// decode
|
||||
std::vector<uint8_t> bin = Radix64::decode(copy);
|
||||
// hash
|
||||
std::vector<uint8_t> sha256 = RsUtil::BinToSha256(bin);
|
||||
// encode
|
||||
std::string out = Radix32::encode(sha256);
|
||||
|
||||
// i2p uses lowercase
|
||||
std::transform(out.begin(), out.end(), out.begin(), ::tolower);
|
||||
out.append(".b32.i2p");
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool inline isAnswerOk(const std::string &answer) {
|
||||
return (answer.compare(0, 2, "OK") == 0);
|
||||
}
|
||||
@ -284,10 +247,8 @@ void p3I2pBob::threadTick()
|
||||
{
|
||||
int sleepTime = 0;
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::stringstream ss;
|
||||
ss << "data_tick mState: " << mState << " mTask: " << mTask << " mBOBState: " << mBOBState << " mPending: " << mPending.size();
|
||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
||||
RS_STACK_MUTEX(mLock);
|
||||
RS_DBG4("data_tick mState: ", mState, " mTask: ", mTask, " mBOBState: ", mBOBState, " mPending: ", mPending.size());
|
||||
}
|
||||
|
||||
sleepTime += stateMachineController();
|
||||
@ -326,15 +287,13 @@ int p3I2pBob::stateMachineBOB()
|
||||
if (mBOBState == bsList) {
|
||||
int counter = 0;
|
||||
while (answer.find("OK Listing done") == std::string::npos) {
|
||||
std::stringstream ss;
|
||||
ss << "stateMachineBOB status check: read loop, counter: " << counter;
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, ss.str());
|
||||
RS_DBG3("stateMachineBOB status check: read loop, counter: ", counter);
|
||||
answer += recv();
|
||||
counter++;
|
||||
}
|
||||
|
||||
if (answer.find(mTunnelName) == std::string::npos) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB status check: tunnel down!");
|
||||
RS_DBG("status check: tunnel down!");
|
||||
// signal error
|
||||
*((bool *)mProcessing->data) = true;
|
||||
}
|
||||
@ -346,12 +305,12 @@ int p3I2pBob::stateMachineBOB()
|
||||
switch (mBOBState) {
|
||||
case bsNewkeysN:
|
||||
key = answer.substr(3, answer.length()-3);
|
||||
mSetting.addr = keyToBase32Addr(key);
|
||||
mSetting.address.base32 = i2p::keyToBase32Addr(key);
|
||||
IndicateConfigChanged();
|
||||
break;
|
||||
case bsGetkeys:
|
||||
key = answer.substr(3, answer.length()-3);
|
||||
mSetting.keys = key;
|
||||
mSetting.address.privateKey = key;
|
||||
IndicateConfigChanged();
|
||||
break;
|
||||
default:
|
||||
@ -374,8 +333,8 @@ int p3I2pBob::stateMachineBOB_locked_failure(const std::string &answer, const bo
|
||||
return sleepFactorDefault;
|
||||
}
|
||||
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB FAILED to run command '" + currentState.command + "'");
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB '" + answer + "'");
|
||||
RS_DBG("FAILED to run command: ", currentState.command);
|
||||
RS_DBG("answer: ", answer);
|
||||
|
||||
mErrorMsg.append("FAILED to run command '" + currentState.command + "'" + '\n');
|
||||
mErrorMsg.append("reason '" + answer + "'" + '\n');
|
||||
@ -422,14 +381,14 @@ int p3I2pBob::stateMachineController()
|
||||
return stateMachineController_locked_idle();
|
||||
case csDoConnect:
|
||||
if (!connectI2P()) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController doConnect: unable to connect");
|
||||
RS_DBG("doConnect: unable to connect");
|
||||
mStateOld = mState;
|
||||
mState = csError;
|
||||
mErrorMsg = "unable to connect to BOB port";
|
||||
return sleepFactorSlow;
|
||||
}
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController doConnect: connected");
|
||||
RS_DBG4("doConnect: connected");
|
||||
mState = csConnected;
|
||||
break;
|
||||
case csConnected:
|
||||
@ -437,7 +396,7 @@ int p3I2pBob::stateMachineController()
|
||||
case csWaitForBob:
|
||||
// check connection problems
|
||||
if (mSocket == 0) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController waitForBob: conection lost");
|
||||
RS_DBG("waitForBob: conection lost");
|
||||
mStateOld = mState;
|
||||
mState = csError;
|
||||
mErrorMsg = "connection lost to BOB";
|
||||
@ -447,21 +406,21 @@ int p3I2pBob::stateMachineController()
|
||||
// check for finished BOB protocol
|
||||
if (mBOBState == bsCleared) {
|
||||
// done
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController waitForBob: mBOBState == bsCleared");
|
||||
RS_DBG4("waitForBob: mBOBState == bsCleared");
|
||||
mState = csDoDisconnect;
|
||||
}
|
||||
break;
|
||||
case csDoDisconnect:
|
||||
if (!disconnectI2P() || mSocket != 0) {
|
||||
// just in case
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController doDisconnect: can't disconnect");
|
||||
RS_DBG("doDisconnect: can't disconnect");
|
||||
mStateOld = mState;
|
||||
mState = csError;
|
||||
mErrorMsg = "unable to disconnect from BOB";
|
||||
return sleepFactorDefault;
|
||||
}
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController doDisconnect: disconnected");
|
||||
RS_DBG4("doDisconnect: disconnected");
|
||||
mState = csDisconnected;
|
||||
break;
|
||||
case csDisconnected:
|
||||
@ -487,12 +446,12 @@ int p3I2pBob::stateMachineController_locked_idle()
|
||||
mProcessing = mPending.front();
|
||||
mPending.pop();
|
||||
|
||||
if (!mSetting.enableBob && (
|
||||
if (!mSetting.enable && (
|
||||
mProcessing->task == autoProxyTask::start ||
|
||||
mProcessing->task == autoProxyTask::stop ||
|
||||
mProcessing->task == autoProxyTask::proxyStatusCheck)) {
|
||||
// skip since we are not enabled
|
||||
rslog(RsLog::Debug_Alert, &i2pBobLogInfo, "stateMachineController_locked_idle: disabled -> skipping ticket");
|
||||
RS_DBG1("disabled -> skipping ticket");
|
||||
rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::disabled);
|
||||
mProcessing = NULL;
|
||||
} else {
|
||||
@ -514,7 +473,7 @@ int p3I2pBob::stateMachineController_locked_idle()
|
||||
mTask = ctRunCheck;
|
||||
break;
|
||||
default:
|
||||
rslog(RsLog::Debug_Alert, &i2pBobLogInfo, "stateMachineController_locked_idle unknown async task");
|
||||
RS_DBG1("unknown async task");
|
||||
rsAutoProxyMonitor::taskError(mProcessing);
|
||||
mProcessing = NULL;
|
||||
break;
|
||||
@ -561,29 +520,29 @@ int p3I2pBob::stateMachineController_locked_connected()
|
||||
switch (mTask) {
|
||||
case ctRunSetUp:
|
||||
// when we have a key use it for server tunnel!
|
||||
if(mSetting.keys.empty()) {
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickC");
|
||||
if(mSetting.address.privateKey.empty()) {
|
||||
RS_DBG4("setting mBOBState = setnickC");
|
||||
mBOBState = bsSetnickC;
|
||||
} else {
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickS");
|
||||
RS_DBG4("setting mBOBState = setnickS");
|
||||
mBOBState = bsSetnickS;
|
||||
}
|
||||
break;
|
||||
case ctRunShutDown:
|
||||
// shut down existing tunnel
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = getnick");
|
||||
RS_DBG4("setting mBOBState = getnick");
|
||||
mBOBState = bsGetnick;
|
||||
break;
|
||||
case ctRunCheck:
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = list");
|
||||
RS_DBG4("setting mBOBState = list");
|
||||
mBOBState = bsList;
|
||||
break;
|
||||
case ctRunGetKeys:
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickN");
|
||||
RS_DBG4("setting mBOBState = setnickN");
|
||||
mBOBState = bsSetnickN;
|
||||
break;
|
||||
case ctIdle:
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_connected: task is idle. This should not happen!");
|
||||
RS_DBG("task is idle. This should not happen!");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -599,7 +558,7 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||
if(errorHappened) {
|
||||
// reset old state
|
||||
mStateOld = csIdel;
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_disconnected: error during process!");
|
||||
RS_DBG("error during process!");
|
||||
}
|
||||
|
||||
// answer ticket
|
||||
@ -628,12 +587,12 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||
mTask = mTaskOld;
|
||||
|
||||
if (!errorHappened) {
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_disconnected: run check result: ok");
|
||||
RS_DBG4("run check result: ok");
|
||||
break;
|
||||
}
|
||||
// switch to error
|
||||
newState = csError;
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_disconnected: run check result: error");
|
||||
RS_DBG("run check result: error");
|
||||
mErrorMsg = "Connection check failed. Will try to restart tunnel.";
|
||||
|
||||
break;
|
||||
@ -656,7 +615,7 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||
mTask = mTaskOld;
|
||||
break;
|
||||
case ctIdle:
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_disconnected: task is idle. This should not happen!");
|
||||
RS_DBG("task is idle. This should not happen!");
|
||||
rsAutoProxyMonitor::taskError(mProcessing);
|
||||
}
|
||||
mProcessing = NULL;
|
||||
@ -672,14 +631,12 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
{
|
||||
// wait for bob protocoll
|
||||
if (mBOBState != bsCleared) {
|
||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, "stateMachineController_locked_error: waiting for BOB");
|
||||
RS_DBG4("waiting for BOB");
|
||||
return sleepFactorFast;
|
||||
}
|
||||
|
||||
#if 0
|
||||
std::stringstream ss;
|
||||
ss << "stateMachineController_locked_error: mProcessing: " << (mProcessing ? "not null" : "null");
|
||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
||||
RS_DBG4("stateMachineController_locked_error: mProcessing: ", (mProcessing ? "not null" : "null"));
|
||||
#endif
|
||||
|
||||
// try to finish ticket
|
||||
@ -687,7 +644,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
switch (mTask) {
|
||||
case ctRunCheck:
|
||||
// connection check failed at some point
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: failed to check proxy status (it's likely dead)!");
|
||||
RS_DBG("failed to check proxy status (it's likely dead)!");
|
||||
*((bool *)mProcessing->data) = true;
|
||||
mState = csDoDisconnect;
|
||||
mStateOld = csIdel;
|
||||
@ -695,7 +652,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
break;
|
||||
case ctRunShutDown:
|
||||
// not a big deal though
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: failed to shut down tunnel (it's likely dead though)!");
|
||||
RS_DBG("failed to shut down tunnel (it's likely dead though)!");
|
||||
mState = csDoDisconnect;
|
||||
mStateOld = csIdel;
|
||||
mErrorMsg.clear();
|
||||
@ -703,14 +660,14 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
case ctIdle:
|
||||
// should not happen but we need to deal with it
|
||||
// this will produce some error messages in the log and finish the task (marked as failed)
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: task is idle. This should not happen!");
|
||||
RS_DBG("task is idle. This should not happen!");
|
||||
mState = csDoDisconnect;
|
||||
mStateOld = csIdel;
|
||||
mErrorMsg.clear();
|
||||
break;
|
||||
case ctRunGetKeys:
|
||||
case ctRunSetUp:
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: failed to receive key / start up");
|
||||
RS_DBG("failed to receive key / start up");
|
||||
mStateOld = csError;
|
||||
mState = csDoDisconnect;
|
||||
// keep the error message
|
||||
@ -721,7 +678,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
|
||||
// periodically retry
|
||||
if (mLastProxyCheck < time(NULL) - (selfCheckPeroid >> 1) && mTask == ctRunSetUp) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: retrying");
|
||||
RS_DBG("retrying");
|
||||
|
||||
mLastProxyCheck = time(NULL);
|
||||
mErrorMsg.clear();
|
||||
@ -734,7 +691,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||
|
||||
// check for new tickets
|
||||
if (!mPending.empty()) {
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_error: processing new ticket");
|
||||
RS_DBG4("processing new ticket");
|
||||
|
||||
// reset and try new task
|
||||
mTask = ctIdle;
|
||||
@ -765,16 +722,16 @@ RsSerialiser *p3I2pBob::setupSerialiser()
|
||||
|
||||
bool p3I2pBob::saveList(bool &cleanup, std::list<RsItem *> &lst)
|
||||
{
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "saveList");
|
||||
RS_DBG4("");
|
||||
|
||||
cleanup = true;
|
||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet;
|
||||
RsTlvKeyValue kv;
|
||||
|
||||
RS_STACK_MUTEX(mLock);
|
||||
addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enableBob ? "TRUE" : "FALSE")
|
||||
addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.keys)
|
||||
addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.addr)
|
||||
addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enable ? "TRUE" : "FALSE")
|
||||
addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.address.privateKey)
|
||||
addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.address.base32)
|
||||
addKVSInt(vitem, kv, kConfigKeyInLength, mSetting.inLength)
|
||||
addKVSInt(vitem, kv, kConfigKeyInQuantity, mSetting.inQuantity)
|
||||
addKVSInt(vitem, kv, kConfigKeyInVariance, mSetting.inVariance)
|
||||
@ -800,7 +757,7 @@ bool p3I2pBob::saveList(bool &cleanup, std::list<RsItem *> &lst)
|
||||
|
||||
bool p3I2pBob::loadList(std::list<RsItem *> &load)
|
||||
{
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "loadList");
|
||||
RS_DBG4("");
|
||||
|
||||
for(std::list<RsItem*>::const_iterator it = load.begin(); it!=load.end(); ++it) {
|
||||
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet*>(*it);
|
||||
@ -808,11 +765,11 @@ bool p3I2pBob::loadList(std::list<RsItem *> &load)
|
||||
RS_STACK_MUTEX(mLock);
|
||||
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) {
|
||||
if (kit->key == kConfigKeyBOBEnable)
|
||||
mSetting.enableBob = kit->value == "TRUE";
|
||||
mSetting.enable = kit->value == "TRUE";
|
||||
else if (kit->key == kConfigKeyBOBKey)
|
||||
mSetting.keys = kit->value;
|
||||
mSetting.address.privateKey = kit->value;
|
||||
else if (kit->key == kConfigKeyBOBAddr)
|
||||
mSetting.addr = kit->value;
|
||||
mSetting.address.base32 = kit->value;
|
||||
getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength)
|
||||
getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity)
|
||||
getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance)
|
||||
@ -820,7 +777,7 @@ bool p3I2pBob::loadList(std::list<RsItem *> &load)
|
||||
getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity)
|
||||
getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance)
|
||||
else
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "loadList unknown key: " + kit->key);
|
||||
RS_DBG("unknown key: ", kit->key);
|
||||
}
|
||||
}
|
||||
delete vitem;
|
||||
@ -884,7 +841,7 @@ void p3I2pBob::getStates(bobStates *bs)
|
||||
|
||||
std::string p3I2pBob::executeCommand(const std::string &command)
|
||||
{
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "executeCommand_locked running '" + command + "'");
|
||||
RS_DBG4("running: ", command);
|
||||
|
||||
std::string copy = command;
|
||||
copy.push_back('\n');
|
||||
@ -896,7 +853,7 @@ std::string p3I2pBob::executeCommand(const std::string &command)
|
||||
// receive answer (trailing new line is already removed!)
|
||||
std::string ans = recv();
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "executeCommand_locked answer '" + ans + "'");
|
||||
RS_DBG4("answer: ", ans);
|
||||
|
||||
return ans;
|
||||
}
|
||||
@ -906,7 +863,7 @@ bool p3I2pBob::connectI2P()
|
||||
// there is only one thread that touches mSocket - no need for a lock
|
||||
|
||||
if (mSocket != 0) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked mSocket != 0");
|
||||
RS_DBG("mSocket != 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -914,21 +871,21 @@ bool p3I2pBob::connectI2P()
|
||||
mSocket = unix_socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (mSocket < 0)
|
||||
{
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked Failed to open socket! Socket Error: " + socket_errorType(errno));
|
||||
RS_DBG("Failed to open socket! Socket Error: ", socket_errorType(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
// connect
|
||||
int err = unix_connect(mSocket, mI2PProxyAddr);
|
||||
if (err != 0) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked Failed to connect to BOB! Socket Error: " + socket_errorType(errno));
|
||||
RS_DBG("Failed to connect to BOB! Socket Error: ", socket_errorType(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
// receive hello msg
|
||||
recv();
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "connectI2P_locked done");
|
||||
RS_DBG4("done");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -937,17 +894,17 @@ bool p3I2pBob::disconnectI2P()
|
||||
// there is only one thread that touches mSocket - no need for a lock
|
||||
|
||||
if (mSocket == 0) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "disconnectI2P_locked mSocket == 0");
|
||||
RS_DBG("mSocket == 0");
|
||||
return true;
|
||||
}
|
||||
|
||||
int err = unix_close(mSocket);
|
||||
if (err != 0) {
|
||||
rslog(RsLog::Warning, &i2pBobLogInfo, "disconnectI2P_locked Failed to close socket! Socket Error: " + socket_errorType(errno));
|
||||
RS_DBG("Failed to close socket! Socket Error: ", socket_errorType(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "disconnectI2P_locked done");
|
||||
RS_DBG4("done");
|
||||
mSocket = 0;
|
||||
return true;
|
||||
}
|
||||
@ -968,7 +925,7 @@ std::string toString(const std::string &a, const int8_t b) {
|
||||
|
||||
void p3I2pBob::finalizeSettings_locked()
|
||||
{
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked");
|
||||
RS_DBG4("");
|
||||
|
||||
sockaddr_storage_clear(mI2PProxyAddr);
|
||||
// get i2p proxy addr
|
||||
@ -979,8 +936,8 @@ void p3I2pBob::finalizeSettings_locked()
|
||||
sockaddr_storage_setipv4(mI2PProxyAddr, (sockaddr_in*)&proxy);
|
||||
sockaddr_storage_setport(mI2PProxyAddr, 2827);
|
||||
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked using " + sockaddr_storage_tostring(mI2PProxyAddr));
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked using " + mSetting.addr);
|
||||
RS_DBG4("using ", mI2PProxyAddr);
|
||||
RS_DBG4("using ", mSetting.address.base32);
|
||||
|
||||
peerState ps;
|
||||
mPeerMgr->getOwnNetStatus(ps);
|
||||
@ -988,21 +945,17 @@ void p3I2pBob::finalizeSettings_locked()
|
||||
// setup commands
|
||||
// new lines are appended later!
|
||||
|
||||
// generate random suffix for name
|
||||
// RSRandom::random_alphaNumericString can return very weird looking strings like: ,,@z+M
|
||||
// use base32 instead
|
||||
size_t len = 5; // 5 characters = 8 base32 symbols
|
||||
std::vector<uint8_t> tmp(len);
|
||||
RSRandom::random_bytes(tmp.data(), len);
|
||||
const std::string location = Radix32::encode(tmp.data(), len);
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked using suffix " + location);
|
||||
// generate 8 characater long random suffix for name
|
||||
constexpr size_t len = 8;
|
||||
const std::string location = RsRandom::alphaNumeric(len);
|
||||
RS_DBG4("using suffix ", location);
|
||||
mTunnelName = "RetroShare-" + location;
|
||||
|
||||
const std::string setnick = "setnick RetroShare-" + location;
|
||||
const std::string getnick = "getnick RetroShare-" + location;
|
||||
const std::string newkeys = "newkeys";
|
||||
const std::string getkeys = "getkeys";
|
||||
const std::string setkeys = "setkeys " + mSetting.keys;
|
||||
const std::string setkeys = "setkeys " + mSetting.address.privateKey;
|
||||
const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy);
|
||||
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
||||
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
||||
@ -1063,7 +1016,7 @@ void p3I2pBob::finalizeSettings_locked()
|
||||
|
||||
void p3I2pBob::updateSettings_locked()
|
||||
{
|
||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "updateSettings_locked");
|
||||
RS_DBG4("");
|
||||
|
||||
sockaddr_storage proxy;
|
||||
mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy);
|
||||
@ -1071,7 +1024,7 @@ void p3I2pBob::updateSettings_locked()
|
||||
peerState ps;
|
||||
mPeerMgr->getOwnNetStatus(ps);
|
||||
|
||||
const std::string setkeys = "setkeys " + mSetting.keys;
|
||||
const std::string setkeys = "setkeys " + mSetting.address.privateKey;
|
||||
const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy);
|
||||
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
||||
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
||||
@ -1103,38 +1056,62 @@ void p3I2pBob::updateSettings_locked()
|
||||
|
||||
std::string p3I2pBob::recv()
|
||||
{
|
||||
// BOB works line based
|
||||
// -> \n indicates and of the line
|
||||
|
||||
constexpr uint16_t bufferSize = 128;
|
||||
char buffer[bufferSize];
|
||||
|
||||
std::string ans;
|
||||
ssize_t length;
|
||||
const uint16_t bufferSize = 128;
|
||||
std::vector<char> buffer(bufferSize);
|
||||
uint16_t retry = 10;
|
||||
|
||||
do {
|
||||
doSleep(sleepTimeRecv);
|
||||
memset(buffer, 0, bufferSize);
|
||||
|
||||
// there is only one thread that touches mSocket - no need for a lock
|
||||
length = ::recv(mSocket, buffer.data(), buffer.size(), 0);
|
||||
if (length < 0)
|
||||
// peek at data
|
||||
auto length = ::recv(mSocket, buffer, bufferSize, MSG_PEEK);
|
||||
if (length <= 0) {
|
||||
if (length < 0) {
|
||||
// error
|
||||
perror(__PRETTY_FUNCTION__);
|
||||
}
|
||||
retry--;
|
||||
doSleep(sleepTimeRecv);
|
||||
continue;
|
||||
}
|
||||
|
||||
ans.append(buffer.begin(), buffer.end());
|
||||
// at least one byte was read
|
||||
|
||||
// clean received string
|
||||
ans.erase(std::remove(ans.begin(), ans.end(), '\0'), ans.end());
|
||||
ans.erase(std::remove(ans.begin(), ans.end(), '\n'), ans.end());
|
||||
// search for new line
|
||||
auto bufferStr = std::string(buffer);
|
||||
size_t pos = bufferStr.find('\n');
|
||||
|
||||
#if 0
|
||||
std::stringstream ss;
|
||||
ss << "recv length: " << length << " (bufferSize: " << bufferSize << ") ans: " << ans.length();
|
||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
||||
#endif
|
||||
if (pos == std::string::npos) {
|
||||
// no new line found -> more to read
|
||||
|
||||
// clear and resize buffer again
|
||||
buffer.clear();
|
||||
buffer.resize(bufferSize);
|
||||
// sanity check
|
||||
if (length != bufferSize) {
|
||||
// expectation: a full buffer was peeked)
|
||||
RS_DBG1("peeked less than bufferSize but also didn't found a new line character");
|
||||
}
|
||||
// this should never happen
|
||||
assert(length <= bufferSize);
|
||||
} else {
|
||||
// new line found -> end of message
|
||||
|
||||
if (this->shouldStop())
|
||||
break;
|
||||
} while(length == bufferSize || ans.size() < 4);
|
||||
// calculate how much there is to read, read the \n, too!
|
||||
length = pos + 1;
|
||||
|
||||
// end loop
|
||||
retry = 0;
|
||||
}
|
||||
|
||||
// now read for real
|
||||
memset(buffer, 0, bufferSize);
|
||||
length = ::recv(mSocket, buffer, length, 0);
|
||||
bufferStr = std::string(buffer);
|
||||
ans.append(bufferStr);
|
||||
} while(retry > 0);
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
@ -30,9 +30,10 @@
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "util/i2pcommon.h"
|
||||
|
||||
/*
|
||||
* This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS
|
||||
@ -49,7 +50,7 @@
|
||||
*
|
||||
* Note 3:
|
||||
* BOB needs a unique name as an ID for each tunnel.
|
||||
* We use 'RetroShare-' + 8 base32 characters.
|
||||
* We use 'RetroShare-' + 8 random base32 characters.
|
||||
*
|
||||
* Design:
|
||||
* The service uses three state machines to manage its task:
|
||||
@ -72,7 +73,7 @@
|
||||
* mCommands[bobState::quit] = {quit, bobState::cleared};
|
||||
*
|
||||
* stateMachineController:
|
||||
* This state machone manages the high level tasks.
|
||||
* This state machine manages the high level tasks.
|
||||
* It is controlled by mState and mTask.
|
||||
*
|
||||
* mTast:
|
||||
@ -162,19 +163,7 @@ struct bobStateInfo {
|
||||
bobState nextState;
|
||||
};
|
||||
|
||||
struct bobSettings {
|
||||
bool enableBob; ///< This field is used by the pqi subsystem to determinine whether SOCKS proxy or BOB is used for I2P connections
|
||||
std::string keys; ///< (optional) server keys
|
||||
std::string addr; ///< (optional) hidden service addr. in base32 form
|
||||
|
||||
int8_t inLength;
|
||||
int8_t inQuantity;
|
||||
int8_t inVariance;
|
||||
|
||||
int8_t outLength;
|
||||
int8_t outQuantity;
|
||||
int8_t outVariance;
|
||||
};
|
||||
struct bobSettings : i2p::settings {};
|
||||
|
||||
///
|
||||
/// \brief The bobStates struct
|
||||
@ -203,8 +192,6 @@ public:
|
||||
void processTaskAsync(taskTicket *ticket);
|
||||
void processTaskSync(taskTicket *ticket);
|
||||
|
||||
static std::string keyToBase32Addr(const std::string &key);
|
||||
|
||||
void threadTick() override; /// @see RsTickingThread
|
||||
|
||||
private:
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "rsautoproxymonitor.h"
|
||||
|
||||
#include <unistd.h> /* for usleep() */
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rstime.h"
|
||||
|
||||
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
|
||||
@ -42,8 +43,10 @@ rsAutoProxyMonitor *rsAutoProxyMonitor::instance()
|
||||
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
|
||||
{
|
||||
RS_STACK_MUTEX(mLock);
|
||||
if (mProxies.find(type) != mProxies.end())
|
||||
std::cerr << "sAutoProxyMonitor::addProxy type " << type << " already added - OVERWRITING" << std::endl;
|
||||
if (mProxies.find(type) != mProxies.end()) {
|
||||
RS_ERR("type ", type, " already added - OVERWRITING");
|
||||
print_stacktrace();
|
||||
}
|
||||
|
||||
mProxies[type] = service;
|
||||
}
|
||||
@ -117,7 +120,7 @@ void rsAutoProxyMonitor::stopAllRSShutdown()
|
||||
do {
|
||||
rstime::rs_usleep(1000 * 1000);
|
||||
RS_STACK_MUTEX(mLock);
|
||||
std::cout << "(II) waiting for auto proxy service(s) to shut down " << t << "/" << timeout << " (remaining: " << mProxies.size() << ")" << std::endl;
|
||||
RS_DBG("waiting for auto proxy service(s) to shut down ", t, "/", timeout, " (remaining: ", mProxies.size(), ")");
|
||||
if (mProxies.empty())
|
||||
break;
|
||||
t++;
|
||||
@ -146,13 +149,16 @@ void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||
{
|
||||
// sanity checks
|
||||
if (!ticket->async && ticket->types.size() > 1) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task synchronous call to multiple services. This can cause problems!" << std::endl;
|
||||
RS_ERR("synchronous call to multiple services. This can cause problems!");
|
||||
print_stacktrace();
|
||||
}
|
||||
if (ticket->async && !ticket->cb && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task asynchronous call with data but no callback. This will likely causes memory leak!" << std::endl;
|
||||
RS_ERR("asynchronous call with data but no callback. This will likely causes memory leak!");
|
||||
print_stacktrace();
|
||||
}
|
||||
if (ticket->types.size() > 1 && ticket->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::task call with data to multiple services. This will likely causes memory leak!" << std::endl;
|
||||
RS_ERR("call with data to multiple services. This will likely causes memory leak!");
|
||||
print_stacktrace();
|
||||
}
|
||||
|
||||
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it;
|
||||
@ -168,7 +174,11 @@ void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||
*tt = *ticket;
|
||||
tt->types.clear();
|
||||
tt->types.push_back(*it);
|
||||
s->processTaskAsync(tt);
|
||||
|
||||
// it's async!
|
||||
RsThread::async([s, tt] {
|
||||
s->processTaskAsync(tt);
|
||||
});
|
||||
} else {
|
||||
s->processTaskSync(ticket);
|
||||
}
|
||||
@ -187,7 +197,8 @@ void rsAutoProxyMonitor::taskAsync(std::vector<autoProxyType::autoProxyType_enum
|
||||
if (!isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskAsync called with a synchronous task!" << std::endl;
|
||||
RS_ERR("called with a synchronous task!");
|
||||
print_stacktrace();
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
@ -215,7 +226,8 @@ void rsAutoProxyMonitor::taskSync(std::vector<autoProxyType::autoProxyType_enum>
|
||||
if (isAsyncTask(task)) {
|
||||
// Usually the services will reject this ticket.
|
||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskSync called with an asynchronous task!" << std::endl;
|
||||
RS_ERR("called with an asynchronous task!");
|
||||
print_stacktrace();
|
||||
}
|
||||
|
||||
taskTicket *tt = getTicket();
|
||||
@ -244,7 +256,8 @@ void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatu
|
||||
t->cb->taskFinished(t);
|
||||
if (t != NULL) {
|
||||
// callack did not clean up properly
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish callback did not clean up!" << std::endl;
|
||||
RS_ERR("callback did not clean up!");
|
||||
print_stacktrace();
|
||||
cleanUp = true;
|
||||
}
|
||||
} else if (t->async){
|
||||
@ -252,12 +265,13 @@ void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatu
|
||||
// we must take care of deleting
|
||||
cleanUp = true;
|
||||
if(t->data)
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish async call with data attached but no callback set!" << std::endl;
|
||||
RS_ERR("async call with data attached but no callback set!");
|
||||
}
|
||||
|
||||
if (cleanUp) {
|
||||
if (t->data) {
|
||||
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish will try to delete void pointer!" << std::endl;
|
||||
RS_ERR("will try to delete void pointer!");
|
||||
print_stacktrace();
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete t->data;
|
||||
@ -290,7 +304,8 @@ void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket)
|
||||
|
||||
// clean up
|
||||
if (ticket->data) {
|
||||
std::cerr << "rsAutoProxyMonitor::taskFinished data set. Will try to delete void pointer" << std::endl;
|
||||
RS_ERR(" data set. Will try to delete void pointer");
|
||||
print_stacktrace();
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||
delete ticket->data;
|
||||
@ -308,7 +323,7 @@ autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType
|
||||
if ((itService = mProxies.find(t)) != mProxies.end()) {
|
||||
return itService->second;
|
||||
}
|
||||
std::cerr << "sAutoProxyMonitor::lookUpService no service for type " << t << " found!" << std::endl;
|
||||
RS_DBG("no service for type ", t, " found!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
163
libretroshare/src/util/i2pcommon.cpp
Normal file
163
libretroshare/src/util/i2pcommon.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
#include "i2pcommon.h"
|
||||
|
||||
#include "util/rsbase64.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
namespace i2p {
|
||||
|
||||
std::string keyToBase32Addr(const std::string &key)
|
||||
{
|
||||
std::string copy(key);
|
||||
|
||||
// replace I2P specific chars
|
||||
std::replace(copy.begin(), copy.end(), '~', '/');
|
||||
// replacing the - with a + is not necessary, as RsBase64 can handle base64url encoding, too
|
||||
// std::replace(copy.begin(), copy.end(), '-', '+');
|
||||
|
||||
// decode
|
||||
std::vector<uint8_t> bin;
|
||||
RsBase64::decode(copy, bin);
|
||||
|
||||
// hash
|
||||
std::vector<uint8_t> sha256 = RsUtil::BinToSha256(bin);
|
||||
// encode
|
||||
std::string out = Radix32::encode(sha256);
|
||||
|
||||
// i2p uses lowercase
|
||||
std::transform(out.begin(), out.end(), out.begin(), ::tolower);
|
||||
out.append(".b32.i2p");
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
const std::string makeOption(const std::string &lhs, const int8_t &rhs) {
|
||||
return lhs + "=" + std::to_string(rhs);
|
||||
}
|
||||
|
||||
uint16_t readTwoBytesBE(std::vector<uint8_t>::const_iterator &p)
|
||||
{
|
||||
uint16_t val = 0;
|
||||
val += *p++;
|
||||
val <<= 8;
|
||||
val += *p++;
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string publicKeyFromPrivate(std::string const &priv)
|
||||
{
|
||||
/*
|
||||
* https://geti2p.net/spec/common-structures#destination
|
||||
* https://geti2p.net/spec/common-structures#keysandcert
|
||||
* https://geti2p.net/spec/common-structures#certificate
|
||||
*/
|
||||
if (priv.length() < 884) // base64 ( = 663 bytes = KeyCert + priv Keys)
|
||||
return std::string();
|
||||
|
||||
// creat a copy to work on, need to convert it to standard base64
|
||||
auto priv_copy(priv);
|
||||
std::replace(priv_copy.begin(), priv_copy.end(), '~', '/');
|
||||
// replacing the - with a + is not necessary, as RsBase64 can handle base64url encoding, too
|
||||
// std::replace(copy.begin(), copy.end(), '-', '+');
|
||||
|
||||
// get raw data
|
||||
std::vector<uint8_t> dataPriv;
|
||||
RsBase64::decode(priv_copy, dataPriv);
|
||||
|
||||
auto p = dataPriv.cbegin();
|
||||
RS_DBG("dataPriv.size ", dataPriv.size());
|
||||
|
||||
size_t publicKeyLen = 256 + 128; // default length (bytes)
|
||||
uint8_t certType = 0;
|
||||
uint16_t len = 0;
|
||||
uint16_t signingKeyType = 0;
|
||||
uint16_t cryptKey = 0;
|
||||
|
||||
// only used for easy break
|
||||
do {
|
||||
try {
|
||||
// jump to certificate
|
||||
p += publicKeyLen;
|
||||
// try to read type and length
|
||||
certType = *p++;
|
||||
len = readTwoBytesBE(p);
|
||||
|
||||
// only 0 and 5 are used / valid at this point
|
||||
// check for == 0
|
||||
if (certType == static_cast<typename std::underlying_type<CertType>::type>(CertType::Null)) {
|
||||
/*
|
||||
* CertType.Null
|
||||
* type null is followed by 0x00 0x00 <END>
|
||||
* so has to be 0!
|
||||
*/
|
||||
RS_DBG("cert is CertType.Null");
|
||||
publicKeyLen += 3; // add 0x00 0x00 0x00
|
||||
|
||||
if (len != 0)
|
||||
// weird
|
||||
RS_DBG("cert is CertType.Null but len != 0");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// check for != 5
|
||||
if (certType != static_cast<typename std::underlying_type<CertType>::type>(CertType::Key)) {
|
||||
// unsupported
|
||||
RS_DBG("cert type ", certType, " is unsupported");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
RS_DBG("cert is CertType.Key");
|
||||
publicKeyLen += 7; // <type 1B> <len 2B> <keyType1 2B> <keyType2 2B> = 1 + 2 + 2 + 2 = 7 bytes
|
||||
|
||||
/*
|
||||
* "Key certificates were introduced in release 0.9.12. Prior to that release, all PublicKeys were 256-byte ElGamal keys, and all SigningPublicKeys were 128-byte DSA-SHA1 keys."
|
||||
* --> there is space for 256+128 bytes, longer keys are splitted and appended to the certificate
|
||||
* We don't need to bother with the splitting here as only the lenght is important!
|
||||
*/
|
||||
|
||||
// Signing Public Key
|
||||
// likely 7
|
||||
signingKeyType = readTwoBytesBE(p);
|
||||
|
||||
RS_DBG("signing pubkey type ", certType);
|
||||
if (signingKeyType >= 3 && signingKeyType <= 6) {
|
||||
RS_DBG("signing pubkey type ", certType, " has oversize");
|
||||
// calculate oversize
|
||||
|
||||
if (signingKeyType >= signingKeyLengths.size()) {
|
||||
// just in case
|
||||
RS_DBG("signing pubkey type ", certType, " cannot be found in size data!");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
auto values = signingKeyLengths[signingKeyType];
|
||||
if (values.first <= 128) {
|
||||
// just in case, it's supposed to be larger!
|
||||
RS_DBG("signing pubkey type ", certType, " is oversize but size calculation would underflow!");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
publicKeyLen += values.first - 128; // 128 = default DSA key length = the space than can be used before the key must be splitted
|
||||
}
|
||||
|
||||
// Crypto Public Key
|
||||
// likely 0
|
||||
cryptKey = readTwoBytesBE(p);
|
||||
RS_DBG("crypto pubkey type ", cryptKey);
|
||||
// info: these are all smaller than the default 256 bytes, so no oversize calculation is needed
|
||||
|
||||
break;
|
||||
} catch (const std::out_of_range &e) {
|
||||
RS_DBG("hit exception! ", e.what());
|
||||
return std::string();
|
||||
}
|
||||
} while(false);
|
||||
|
||||
std::string pub;
|
||||
auto data2 = std::vector<uint8_t>(dataPriv.cbegin(), dataPriv.cbegin() + publicKeyLen);
|
||||
RsBase64::encode(data2.data(), data2.size(), pub, false, false);
|
||||
|
||||
return pub;
|
||||
}
|
||||
|
||||
} // namespace i2p
|
211
libretroshare/src/util/i2pcommon.h
Normal file
211
libretroshare/src/util/i2pcommon.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef I2PCOMMON_H
|
||||
#define I2PCOMMON_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include "util/rsrandom.h"
|
||||
#include "util/radix32.h"
|
||||
#include "util/rsbase64.h"
|
||||
#include "util/rsprint.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
/*
|
||||
* This header provides common code for i2p related code, namely BOB and SAM3 support.
|
||||
*/
|
||||
|
||||
namespace i2p {
|
||||
|
||||
static constexpr int8_t kDefaultLength = 3; // i2p default
|
||||
static constexpr int8_t kDefaultQuantity = 3; // i2p default + 1
|
||||
static constexpr int8_t kDefaultVariance = 0;
|
||||
static constexpr int8_t kDefaultBackupQuantity = 0;
|
||||
|
||||
/**
|
||||
* @brief The address struct
|
||||
* This structure is a container for any i2p address/key. The public key is used for addressing and can be (optionally) hashed to generate the .b32.i2p address.
|
||||
*/
|
||||
struct address {
|
||||
std::string base32;
|
||||
std::string publicKey;
|
||||
std::string privateKey;
|
||||
|
||||
void clear() {
|
||||
base32.clear();
|
||||
publicKey.clear();
|
||||
privateKey.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The settings struct
|
||||
* Common structure with all settings that are shared between any i2p backends
|
||||
*/
|
||||
struct settings {
|
||||
bool enable;
|
||||
struct address address;
|
||||
|
||||
// connection parameter
|
||||
int8_t inLength;
|
||||
int8_t inQuantity;
|
||||
int8_t inVariance;
|
||||
int8_t inBackupQuantity;
|
||||
|
||||
int8_t outLength;
|
||||
int8_t outQuantity;
|
||||
int8_t outVariance;
|
||||
int8_t outBackupQuantity;
|
||||
|
||||
void initDefault() {
|
||||
enable = false;
|
||||
address.clear();
|
||||
|
||||
inLength = kDefaultLength;
|
||||
inQuantity = kDefaultQuantity;
|
||||
inVariance = kDefaultVariance;
|
||||
inBackupQuantity = kDefaultBackupQuantity;
|
||||
|
||||
outLength = kDefaultLength;
|
||||
outQuantity = kDefaultQuantity;
|
||||
outVariance = kDefaultVariance;
|
||||
outBackupQuantity = kDefaultBackupQuantity;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Type Type Code Payload Length Total Length Notes
|
||||
Null 0 0 3
|
||||
HashCash 1 varies varies Experimental, unused. Payload contains an ASCII colon-separated hashcash string.
|
||||
Hidden 2 0 3 Experimental, unused. Hidden routers generally do not announce that they are hidden.
|
||||
Signed 3 40 or 72 43 or 75 Experimental, unused. Payload contains a 40-byte DSA signature, optionally followed by the 32-byte Hash of the signing Destination.
|
||||
Multiple 4 varies varies Experimental, unused. Payload contains multiple certificates.
|
||||
Key 5 4+ 7+ Since 0.9.12. See below for details.
|
||||
*/
|
||||
enum class CertType : uint8_t {
|
||||
Null = 0,
|
||||
HashCash = 1,
|
||||
Hidden = 2,
|
||||
Signed = 3,
|
||||
Multiple = 4,
|
||||
Key = 5
|
||||
};
|
||||
|
||||
/*
|
||||
* public
|
||||
Type Type Code Total Public Key Length Since Usage
|
||||
DSA_SHA1 0 128 0.9.12 Legacy Router Identities and Destinations, never explicitly set
|
||||
ECDSA_SHA256_P256 1 64 0.9.12 Older Destinations
|
||||
ECDSA_SHA384_P384 2 96 0.9.12 Rarely if ever used for Destinations
|
||||
ECDSA_SHA512_P521 3 132 0.9.12 Rarely if ever used for Destinations
|
||||
RSA_SHA256_2048 4 256 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
RSA_SHA384_3072 5 384 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
RSA_SHA512_4096 6 512 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 7 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 8 32 0.9.25 Offline only; never used in Key Certificates for Router Identities or Destinations
|
||||
reserved (GOST) 9 64 Reserved, see proposal 134
|
||||
reserved (GOST) 10 128 Reserved, see proposal 134
|
||||
RedDSA_SHA512_Ed25519 11 32 0.9.39 For Destinations and encrypted leasesets only; never used for Router Identities
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
|
||||
* private
|
||||
Type Length (bytes) Since Usage
|
||||
DSA_SHA1 20 Legacy Router Identities and Destinations
|
||||
ECDSA_SHA256_P256 32 0.9.12 Recent Destinations
|
||||
ECDSA_SHA384_P384 48 0.9.12 Rarely used for Destinations
|
||||
ECDSA_SHA512_P521 66 0.9.12 Rarely used for Destinations
|
||||
RSA_SHA256_2048 512 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA384_3072 768 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
RSA_SHA512_4096 1024 0.9.12 Offline signing, never used for Router Identities or Destinations
|
||||
EdDSA_SHA512_Ed25519 32 0.9.15 Recent Router Identities and Destinations
|
||||
EdDSA_SHA512_Ed25519ph 32 0.9.25 Offline signing, never used for Router Identities or Destinations
|
||||
RedDSA_SHA512_Ed25519 32 0.9.39 For Destinations and encrypted leasesets only, never used for Router Identities
|
||||
*/
|
||||
enum class SigningKeyType : uint16_t {
|
||||
DSA_SHA1 = 0,
|
||||
ECDSA_SHA256_P256 = 1,
|
||||
ECDSA_SHA384_P384 = 2,
|
||||
ECDSA_SHA512_P521 = 3,
|
||||
RSA_SHA256_2048 = 4,
|
||||
RSA_SHA384_3072 = 5,
|
||||
RSA_SHA512_4096 = 6,
|
||||
EdDSA_SHA512_Ed25519 = 7,
|
||||
EdDSA_SHA512_Ed25519ph = 8,
|
||||
RedDSA_SHA512_Ed25519 = 11
|
||||
};
|
||||
|
||||
/*
|
||||
* public
|
||||
Type Type Code Total Public Key Length Usage
|
||||
ElGamal 0 256 All Router Identities and Destinations
|
||||
P256 1 64 Reserved, see proposal 145
|
||||
P384 2 96 Reserved, see proposal 145
|
||||
P521 3 132 Reserved, see proposal 145
|
||||
X25519 4 32 Not for use in key certs. See proposal 144
|
||||
reserved 65280-65534 Reserved for experimental use
|
||||
reserved 65535 Reserved for future expansion
|
||||
|
||||
* private
|
||||
Type Length (bytes) Since Usage
|
||||
ElGamal 256 All Router Identities and Destinations
|
||||
P256 32 TBD Reserved, see proposal 145
|
||||
P384 48 TBD Reserved, see proposal 145
|
||||
P521 66 TBD Reserved, see proposal 145
|
||||
X25519 32 0.9.38 Little-endian. See proposal 144
|
||||
*/
|
||||
enum class CryptoKeyType : uint16_t {
|
||||
ElGamal = 0,
|
||||
P256 = 1,
|
||||
P384 = 2,
|
||||
P521 = 3,
|
||||
X25519 = 4
|
||||
};
|
||||
|
||||
static const std::array<std::pair<uint16_t, uint16_t>, 5> cryptoKeyLengths {
|
||||
/*CryptoKeyType::ElGamal*/ std::make_pair<uint16_t, uint16_t>(256, 256),
|
||||
/*CryptoKeyType::P256, */ std::make_pair<uint16_t, uint16_t>( 64, 32),
|
||||
/*CryptoKeyType::P384, */ std::make_pair<uint16_t, uint16_t>( 96, 48),
|
||||
/*CryptoKeyType::P521, */ std::make_pair<uint16_t, uint16_t>(132, 66),
|
||||
/*CryptoKeyType::X25519,*/ std::make_pair<uint16_t, uint16_t>( 32, 32),
|
||||
};
|
||||
|
||||
static const std::array<std::pair<uint16_t, uint16_t>, 12> signingKeyLengths {
|
||||
/*SigningKeyType::DSA_SHA1, */ std::make_pair<uint16_t, uint16_t>(128, 128),
|
||||
/*SigningKeyType::ECDSA_SHA256_P256, */ std::make_pair<uint16_t, uint16_t>( 64, 32),
|
||||
/*SigningKeyType::ECDSA_SHA384_P384, */ std::make_pair<uint16_t, uint16_t>( 96, 48),
|
||||
/*SigningKeyType::ECDSA_SHA512_P521, */ std::make_pair<uint16_t, uint16_t>(132, 66),
|
||||
/*SigningKeyType::RSA_SHA256_2048, */ std::make_pair<uint16_t, uint16_t>(256, 512),
|
||||
/*SigningKeyType::RSA_SHA384_3072, */ std::make_pair<uint16_t, uint16_t>(384, 768),
|
||||
/*SigningKeyType::RSA_SHA512_4096, */ std::make_pair<uint16_t, uint16_t>(512,1024),
|
||||
/*SigningKeyType::EdDSA_SHA512_Ed25519 */ std::make_pair<uint16_t, uint16_t>( 32, 32),
|
||||
/*SigningKeyType::EdDSA_SHA512_Ed25519ph */ std::make_pair<uint16_t, uint16_t>( 32, 32),
|
||||
/*reserved (GOST) */ std::make_pair<uint16_t, uint16_t>( 64, 0),
|
||||
/*reserved (GOST) */ std::make_pair<uint16_t, uint16_t>(128, 0),
|
||||
/*SigningKeyType::RedDSA_SHA512_Ed25519 */ std::make_pair<uint16_t, uint16_t>( 32, 32),
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief makeOption Creates the string "lhs=rhs" used by BOB and SAM. Converts rhs
|
||||
* @param lhs option to set
|
||||
* @param rhs value to set
|
||||
* @return concatenated string
|
||||
*/
|
||||
const std::string makeOption(const std::string &lhs, const int8_t &rhs);
|
||||
|
||||
/**
|
||||
* @brief keyToBase32Addr generated a base32 address (.b32.i2p) from a given public key
|
||||
* @param key public key
|
||||
* @return generated base32 address
|
||||
*/
|
||||
std::string keyToBase32Addr(const std::string &key);
|
||||
|
||||
/**
|
||||
* @brief publicKeyFromPrivate parses the private key and calculates the lenght of the public key
|
||||
* @param priv private key (which includes the public key) to read
|
||||
* @return public key used for addressing
|
||||
*/
|
||||
std::string publicKeyFromPrivate(const std::string &priv);
|
||||
|
||||
} // namespace i2p
|
||||
|
||||
#endif // I2PCOMMON_H
|
@ -340,6 +340,10 @@ void GenCertDialog::setupState()
|
||||
ui.hiddenport_spinBox->setVisible(hidden_state && !tor_auto);
|
||||
|
||||
ui.cbUseBob->setVisible(hidden_state && !tor_auto);
|
||||
#ifndef RS_USE_I2P_BOB
|
||||
ui.cbUseBob->setDisabled(true);
|
||||
ui.cbUseBob->setToolTip(tr("BOB support is not available"));
|
||||
#endif
|
||||
|
||||
if(!mAllFieldsOk)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <gui/notifyqt.h>
|
||||
#include "rshare.h"
|
||||
#include "rsharesettings.h"
|
||||
#include "util/i2pcommon.h"
|
||||
#include "util/RsNetUtil.h"
|
||||
#include "util/misc.h"
|
||||
|
||||
@ -82,6 +83,10 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||
manager = NULL ;
|
||||
mOngoingConnectivityCheck = -1;
|
||||
|
||||
#ifndef RS_USE_I2P_BOB
|
||||
ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P_BOB); // warning: the order of operation here is very important.
|
||||
#endif
|
||||
|
||||
if(RsAccounts::isHiddenNode())
|
||||
{
|
||||
if(RsAccounts::isTorAuto())
|
||||
@ -1352,7 +1357,7 @@ void ServerPage::updateInProxyIndicator()
|
||||
ui.iconlabel_service_incoming->setMovie(movie);
|
||||
movie->start();
|
||||
|
||||
if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enableBob) {
|
||||
if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enable) {
|
||||
|
||||
QTcpSocket tcpSocket;
|
||||
|
||||
@ -1439,15 +1444,16 @@ void ServerPage::getNewKey()
|
||||
|
||||
void ServerPage::loadKey()
|
||||
{
|
||||
mBobSettings.keys = ui.pteBobServerKey->toPlainText().toStdString();
|
||||
mBobSettings.addr = p3I2pBob::keyToBase32Addr(mBobSettings.keys);
|
||||
mBobSettings.address.privateKey = ui.pteBobServerKey->toPlainText().toStdString();
|
||||
mBobSettings.address.publicKey = i2p::publicKeyFromPrivate(mBobSettings.address.privateKey);
|
||||
mBobSettings.address.base32 = i2p::keyToBase32Addr(mBobSettings.address.publicKey);
|
||||
|
||||
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
||||
}
|
||||
|
||||
void ServerPage::enableBob(bool checked)
|
||||
{
|
||||
mBobSettings.enableBob = checked;
|
||||
mBobSettings.enable = checked;
|
||||
|
||||
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
||||
|
||||
@ -1487,7 +1493,7 @@ void ServerPage::toggleBobAdvancedSettings(bool checked)
|
||||
{
|
||||
ui.swBobAdvanced->setCurrentIndex(checked ? 1 : 0);
|
||||
|
||||
if (!mBobSettings.keys.empty()) {
|
||||
if (!mBobSettings.address.privateKey.empty()) {
|
||||
if (checked) {
|
||||
ui.pbBobGenAddr->show();
|
||||
} else {
|
||||
@ -1578,9 +1584,9 @@ void ServerPage::loadCommon()
|
||||
whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab
|
||||
|
||||
// don't use whileBlocking here
|
||||
ui.cb_enableBob->setChecked(mBobSettings.enableBob);
|
||||
ui.cb_enableBob->setChecked(mBobSettings.enable);
|
||||
|
||||
if (!mBobSettings.keys.empty()) {
|
||||
if (!mBobSettings.address.privateKey.empty()) {
|
||||
ui.lBobB32Addr->show();
|
||||
ui.leBobB32Addr->show();
|
||||
}
|
||||
@ -1623,13 +1629,13 @@ void ServerPage::saveBob()
|
||||
|
||||
void ServerPage::updateStatusBob()
|
||||
{
|
||||
QString addr = QString::fromStdString(mBobSettings.addr);
|
||||
QString addr = QString::fromStdString(mBobSettings.address.base32);
|
||||
if (ui.leBobB32Addr->text() != addr) {
|
||||
ui.leBobB32Addr->setText(addr);
|
||||
ui.hiddenpage_serviceAddress->setText(addr);
|
||||
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.keys));
|
||||
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey));
|
||||
|
||||
if (!mBobSettings.keys.empty()) {
|
||||
if (!mBobSettings.address.privateKey.empty()) {
|
||||
// we have an addr -> show fields
|
||||
ui.lBobB32Addr->show();
|
||||
ui.leBobB32Addr->show();
|
||||
@ -1655,7 +1661,7 @@ void ServerPage::updateStatusBob()
|
||||
QString bobSimpleText = QString();
|
||||
bobSimpleText.append(tr("RetroShare uses BOB to set up a %1 tunnel at %2:%3 (named %4)\n\n"
|
||||
"When changing options (e.g. port) use the buttons at the bottom to restart BOB.\n\n").
|
||||
arg(mBobSettings.keys.empty() ? tr("client") : tr("server"),
|
||||
arg(mBobSettings.address.privateKey.empty() ? tr("client") : tr("server"),
|
||||
ui.hiddenpage_proxyAddress_i2p_2->text(),
|
||||
ui.hiddenpage_proxyPort_i2p_2->text(),
|
||||
bs.tunnelName.empty() ? tr("unknown") :
|
||||
@ -1777,15 +1783,15 @@ void ServerPage::updateStatusBob()
|
||||
|
||||
void ServerPage::setUpBobElements()
|
||||
{
|
||||
ui.gbBob->setEnabled(mBobSettings.enableBob);
|
||||
if (mBobSettings.enableBob) {
|
||||
ui.gbBob->setEnabled(mBobSettings.enable);
|
||||
if (mBobSettings.enable) {
|
||||
ui.hiddenpage_proxyAddress_i2p->setEnabled(false);
|
||||
ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
||||
ui.hiddenpage_proxyPort_i2p->setEnabled(false);
|
||||
ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
||||
|
||||
ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.addr));
|
||||
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.keys));
|
||||
ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.address.base32));
|
||||
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey));
|
||||
|
||||
// cast to int to avoid problems
|
||||
int li, lo, qi, qo, vi, vo;
|
||||
|
@ -140,6 +140,11 @@ rs_macos10.15:CONFIG -= rs_macos10.11
|
||||
CONFIG *= no_rs_jsonapi
|
||||
rs_jsonapi:CONFIG -= no_rs_jsonapi
|
||||
|
||||
# Disable i2p BOB support for automatically setting up an i2p tunnel for RS
|
||||
# "CONFIG+=no_rs_bob"
|
||||
CONFIG *= rs_bob
|
||||
no_rs_bob:CONFIG -= rs_bob
|
||||
|
||||
# To enable channel indexing append the following assignation to qmake command
|
||||
# line "CONFIG+=rs_deep_channel_index"
|
||||
CONFIG *= no_rs_deep_channel_index
|
||||
@ -550,6 +555,10 @@ rs_webui {
|
||||
DEFINES *= RS_WEBUI
|
||||
}
|
||||
|
||||
rs_bob {
|
||||
DEFINES *= RS_USE_I2P_BOB
|
||||
}
|
||||
|
||||
rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX
|
||||
|
||||
rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX
|
||||
|
Loading…
x
Reference in New Issue
Block a user