mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-23 14:41:04 -04:00
Merge pull request #1971 from sehraf/pr_i2p_refactoring
i2p refactoring
This commit is contained in:
commit
891d7e7c9a
11 changed files with 583 additions and 201 deletions
|
@ -154,6 +154,7 @@ rs_webui {
|
||||||
HEADERS += plugins/pluginmanager.h \
|
HEADERS += plugins/pluginmanager.h \
|
||||||
plugins/dlfcn_win32.h \
|
plugins/dlfcn_win32.h \
|
||||||
rsitems/rspluginitems.h \
|
rsitems/rspluginitems.h \
|
||||||
|
util/i2pcommon.h \
|
||||||
util/rsinitedptr.h
|
util/rsinitedptr.h
|
||||||
|
|
||||||
HEADERS += $$PUBLIC_HEADERS
|
HEADERS += $$PUBLIC_HEADERS
|
||||||
|
@ -517,7 +518,8 @@ SOURCES += ft/ftchunkmap.cc \
|
||||||
ft/ftfilesearch.cc \
|
ft/ftfilesearch.cc \
|
||||||
ft/ftserver.cc \
|
ft/ftserver.cc \
|
||||||
ft/fttransfermodule.cc \
|
ft/fttransfermodule.cc \
|
||||||
ft/ftturtlefiletransferitem.cc
|
ft/ftturtlefiletransferitem.cc \
|
||||||
|
util/i2pcommon.cpp
|
||||||
|
|
||||||
SOURCES += crypto/chacha20.cpp \
|
SOURCES += crypto/chacha20.cpp \
|
||||||
crypto/hashstream.cc\
|
crypto/hashstream.cc\
|
||||||
|
|
|
@ -161,7 +161,9 @@ public:
|
||||||
p3ChatService *chatSrv;
|
p3ChatService *chatSrv;
|
||||||
p3StatusService *mStatusSrv;
|
p3StatusService *mStatusSrv;
|
||||||
p3GxsTunnelService *mGxsTunnels;
|
p3GxsTunnelService *mGxsTunnels;
|
||||||
|
#ifdef RS_USE_I2P_BOB
|
||||||
p3I2pBob *mI2pBob;
|
p3I2pBob *mI2pBob;
|
||||||
|
#endif
|
||||||
|
|
||||||
// This list contains all threaded services. It will be used to shut them down properly.
|
// 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);
|
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
|
||||||
|
|
||||||
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
|
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
|
||||||
|
#ifdef RS_USE_I2P_BOB
|
||||||
mI2pBob = new p3I2pBob(mPeerMgr);
|
mI2pBob = new p3I2pBob(mPeerMgr);
|
||||||
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
|
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
|
||||||
|
#endif
|
||||||
|
|
||||||
//load all the SSL certs as friends
|
//load all the SSL certs as friends
|
||||||
// std::list<std::string> sslIds;
|
// std::list<std::string> sslIds;
|
||||||
|
@ -1649,7 +1651,9 @@ int RsServer::StartupRetroShare()
|
||||||
mConfigMgr->addConfiguration("wire.cfg", wire_ns);
|
mConfigMgr->addConfiguration("wire.cfg", wire_ns);
|
||||||
#endif
|
#endif
|
||||||
#endif //RS_ENABLE_GXS
|
#endif //RS_ENABLE_GXS
|
||||||
|
#ifdef RS_USE_I2P_BOB
|
||||||
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
|
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
|
||||||
|
#endif
|
||||||
|
|
||||||
mPluginsManager->addConfigurations(mConfigMgr) ;
|
mPluginsManager->addConfigurations(mConfigMgr) ;
|
||||||
|
|
||||||
|
@ -1724,7 +1728,7 @@ int RsServer::StartupRetroShare()
|
||||||
// now enable bob
|
// now enable bob
|
||||||
bobSettings bs;
|
bobSettings bs;
|
||||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
|
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
|
||||||
bs.enableBob = true;
|
bs.enable = true;
|
||||||
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
|
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
|
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
|
||||||
|
@ -1795,7 +1799,9 @@ int RsServer::StartupRetroShare()
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
// auto proxy threads
|
// auto proxy threads
|
||||||
|
#ifdef RS_USE_I2P_BOB
|
||||||
startServiceThread(mI2pBob, "I2P-BOB");
|
startServiceThread(mI2pBob, "I2P-BOB");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RS_ENABLE_GXS
|
#ifdef RS_ENABLE_GXS
|
||||||
// Must Set the GXS pointers before starting threads.
|
// 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 kConfigKeyOutQuantity = "OUT_QUANTITY";
|
||||||
static const std::string kConfigKeyOutVariance = "OUT_VARIANCE";
|
static const std::string kConfigKeyOutVariance = "OUT_VARIANCE";
|
||||||
|
|
||||||
static const bool kDefaultBOBEnable = false;
|
/// Sleep duration for receiving loop in error/no-data case
|
||||||
static const int8_t kDefaultLength = 3;
|
static const useconds_t sleepTimeRecv = 250; // times 1000 = 250ms
|
||||||
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 everything else
|
/// Sleep duration for everything else
|
||||||
static const useconds_t sleepTimeWait = 50; // times 1000 = 50ms or 0.05s
|
static const useconds_t sleepTimeWait = 50; // times 1000 = 50ms or 0.05s
|
||||||
static const int sleepFactorDefault = 10; // 0.5s
|
static const int sleepFactorDefault = 10; // 0.5s
|
||||||
static const int sleepFactorFast = 1; // 0.05s
|
static const int sleepFactorFast = 1; // 0.05s
|
||||||
static const int sleepFactorSlow = 20; // 1s
|
static const int sleepFactorSlow = 20; // 1s
|
||||||
|
|
||||||
static struct RsLog::logInfo i2pBobLogInfo = {RsLog::Default, "p3I2pBob"};
|
|
||||||
|
|
||||||
static const rstime_t selfCheckPeroid = 30;
|
static const rstime_t selfCheckPeroid = 30;
|
||||||
|
|
||||||
void doSleep(useconds_t timeToSleepMS) {
|
void doSleep(useconds_t timeToSleepMS) {
|
||||||
|
@ -74,15 +67,7 @@ p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr)
|
||||||
mProcessing(NULL), mLock("I2P-BOB")
|
mProcessing(NULL), mLock("I2P-BOB")
|
||||||
{
|
{
|
||||||
// set defaults
|
// set defaults
|
||||||
mSetting.enableBob = kDefaultBOBEnable;
|
mSetting.initDefault();
|
||||||
mSetting.keys = "";
|
|
||||||
mSetting.addr = "";
|
|
||||||
mSetting.inLength = kDefaultLength;
|
|
||||||
mSetting.inQuantity = kDefaultQuantity;
|
|
||||||
mSetting.inVariance = kDefaultVariance;
|
|
||||||
mSetting.outLength = kDefaultLength;
|
|
||||||
mSetting.outQuantity = kDefaultQuantity;
|
|
||||||
mSetting.outVariance = kDefaultVariance;
|
|
||||||
|
|
||||||
mCommands.clear();
|
mCommands.clear();
|
||||||
}
|
}
|
||||||
|
@ -90,12 +75,12 @@ p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr)
|
||||||
bool p3I2pBob::isEnabled()
|
bool p3I2pBob::isEnabled()
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
return mSetting.enableBob;
|
return mSetting.enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||||
{
|
{
|
||||||
std::cout << "p3I2pBob::initialSetup" << std::endl;
|
RS_DBG("");
|
||||||
|
|
||||||
// update config
|
// 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
|
// request keys
|
||||||
// p3I2pBob::stateMachineBOB expects mProcessing to be set therefore
|
// 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;
|
fakeTicket->task = autoProxyTask::receiveKey;
|
||||||
processTaskAsync(fakeTicket);
|
processTaskAsync(fakeTicket);
|
||||||
|
|
||||||
std::cout << "p3I2pBob::initialSetup fakeTicket requested" << std::endl;
|
RS_DBG("fakeTicket requested");
|
||||||
|
|
||||||
// now start thread
|
// now start thread
|
||||||
start("I2P-BOB gen key");
|
start("I2P-BOB gen key");
|
||||||
|
|
||||||
std::cout << "p3I2pBob::initialSetup thread started" << std::endl;
|
RS_DBG("thread started");
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
// wait for keys
|
// wait for keys
|
||||||
|
@ -137,24 +122,24 @@ bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (++counter > 30) {
|
if (++counter > 30) {
|
||||||
std::cout << "p3I2pBob::initialSetup timeout!" << std::endl;
|
RS_DBG4("timeout!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "p3I2pBob::initialSetup got keys" << std::endl;
|
RS_DBG("got keys");
|
||||||
|
|
||||||
// stop thread
|
// stop thread
|
||||||
fullstop();
|
fullstop();
|
||||||
|
|
||||||
std::cout << "p3I2pBob::initialSetup thread stopped" << std::endl;
|
RS_DBG("thread stopped");
|
||||||
|
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mLock);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +157,7 @@ void p3I2pBob::processTaskAsync(taskTicket *ticket)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::processTaskAsync unknown task");
|
RS_DBG("unknown task");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +172,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||||
case autoProxyTask::status:
|
case autoProxyTask::status:
|
||||||
// check if everything needed is set
|
// check if everything needed is set
|
||||||
if (!data) {
|
if (!data) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::status autoProxyTask::status data is missing");
|
RS_DBG("autoProxyTask::status data is missing");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +186,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||||
case autoProxyTask::getSettings:
|
case autoProxyTask::getSettings:
|
||||||
// check if everything needed is set
|
// check if everything needed is set
|
||||||
if (!data) {
|
if (!data) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::getSettings data is missing");
|
RS_DBG("autoProxyTask::getSettings data is missing");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +200,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||||
case autoProxyTask::setSettings:
|
case autoProxyTask::setSettings:
|
||||||
// check if everything needed is set
|
// check if everything needed is set
|
||||||
if (!data) {
|
if (!data) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::setSettings data is missing");
|
RS_DBG("autoProxyTask::setSettings data is missing");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +220,7 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||||
break;
|
break;
|
||||||
case autoProxyTask::getErrorInfo:
|
case autoProxyTask::getErrorInfo:
|
||||||
if (!data) {
|
if (!data) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::data_tick autoProxyTask::getErrorInfo data is missing");
|
RS_DBG("autoProxyTask::getErrorInfo data is missing");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
} else {
|
} else {
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
|
@ -244,34 +229,12 @@ void p3I2pBob::processTaskSync(taskTicket *ticket)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "p3I2pBob::processTaskSync unknown task");
|
RS_DBG("unknown task");
|
||||||
rsAutoProxyMonitor::taskError(ticket);
|
rsAutoProxyMonitor::taskError(ticket);
|
||||||
break;
|
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) {
|
bool inline isAnswerOk(const std::string &answer) {
|
||||||
return (answer.compare(0, 2, "OK") == 0);
|
return (answer.compare(0, 2, "OK") == 0);
|
||||||
}
|
}
|
||||||
|
@ -285,9 +248,7 @@ void p3I2pBob::threadTick()
|
||||||
int sleepTime = 0;
|
int sleepTime = 0;
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
std::stringstream ss;
|
RS_DBG4("data_tick mState: ", mState, " mTask: ", mTask, " mBOBState: ", mBOBState, " mPending: ", mPending.size());
|
||||||
ss << "data_tick mState: " << mState << " mTask: " << mTask << " mBOBState: " << mBOBState << " mPending: " << mPending.size();
|
|
||||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sleepTime += stateMachineController();
|
sleepTime += stateMachineController();
|
||||||
|
@ -326,15 +287,13 @@ int p3I2pBob::stateMachineBOB()
|
||||||
if (mBOBState == bsList) {
|
if (mBOBState == bsList) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
while (answer.find("OK Listing done") == std::string::npos) {
|
while (answer.find("OK Listing done") == std::string::npos) {
|
||||||
std::stringstream ss;
|
RS_DBG3("stateMachineBOB status check: read loop, counter: ", counter);
|
||||||
ss << "stateMachineBOB status check: read loop, counter: " << counter;
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, ss.str());
|
|
||||||
answer += recv();
|
answer += recv();
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (answer.find(mTunnelName) == std::string::npos) {
|
if (answer.find(mTunnelName) == std::string::npos) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB status check: tunnel down!");
|
RS_DBG("status check: tunnel down!");
|
||||||
// signal error
|
// signal error
|
||||||
*((bool *)mProcessing->data) = true;
|
*((bool *)mProcessing->data) = true;
|
||||||
}
|
}
|
||||||
|
@ -346,12 +305,12 @@ int p3I2pBob::stateMachineBOB()
|
||||||
switch (mBOBState) {
|
switch (mBOBState) {
|
||||||
case bsNewkeysN:
|
case bsNewkeysN:
|
||||||
key = answer.substr(3, answer.length()-3);
|
key = answer.substr(3, answer.length()-3);
|
||||||
mSetting.addr = keyToBase32Addr(key);
|
mSetting.address.base32 = i2p::keyToBase32Addr(key);
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
break;
|
break;
|
||||||
case bsGetkeys:
|
case bsGetkeys:
|
||||||
key = answer.substr(3, answer.length()-3);
|
key = answer.substr(3, answer.length()-3);
|
||||||
mSetting.keys = key;
|
mSetting.address.privateKey = key;
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -374,8 +333,8 @@ int p3I2pBob::stateMachineBOB_locked_failure(const std::string &answer, const bo
|
||||||
return sleepFactorDefault;
|
return sleepFactorDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB FAILED to run command '" + currentState.command + "'");
|
RS_DBG("FAILED to run command: ", currentState.command);
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineBOB '" + answer + "'");
|
RS_DBG("answer: ", answer);
|
||||||
|
|
||||||
mErrorMsg.append("FAILED to run command '" + currentState.command + "'" + '\n');
|
mErrorMsg.append("FAILED to run command '" + currentState.command + "'" + '\n');
|
||||||
mErrorMsg.append("reason '" + answer + "'" + '\n');
|
mErrorMsg.append("reason '" + answer + "'" + '\n');
|
||||||
|
@ -422,14 +381,14 @@ int p3I2pBob::stateMachineController()
|
||||||
return stateMachineController_locked_idle();
|
return stateMachineController_locked_idle();
|
||||||
case csDoConnect:
|
case csDoConnect:
|
||||||
if (!connectI2P()) {
|
if (!connectI2P()) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController doConnect: unable to connect");
|
RS_DBG("doConnect: unable to connect");
|
||||||
mStateOld = mState;
|
mStateOld = mState;
|
||||||
mState = csError;
|
mState = csError;
|
||||||
mErrorMsg = "unable to connect to BOB port";
|
mErrorMsg = "unable to connect to BOB port";
|
||||||
return sleepFactorSlow;
|
return sleepFactorSlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController doConnect: connected");
|
RS_DBG4("doConnect: connected");
|
||||||
mState = csConnected;
|
mState = csConnected;
|
||||||
break;
|
break;
|
||||||
case csConnected:
|
case csConnected:
|
||||||
|
@ -437,7 +396,7 @@ int p3I2pBob::stateMachineController()
|
||||||
case csWaitForBob:
|
case csWaitForBob:
|
||||||
// check connection problems
|
// check connection problems
|
||||||
if (mSocket == 0) {
|
if (mSocket == 0) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController waitForBob: conection lost");
|
RS_DBG("waitForBob: conection lost");
|
||||||
mStateOld = mState;
|
mStateOld = mState;
|
||||||
mState = csError;
|
mState = csError;
|
||||||
mErrorMsg = "connection lost to BOB";
|
mErrorMsg = "connection lost to BOB";
|
||||||
|
@ -447,21 +406,21 @@ int p3I2pBob::stateMachineController()
|
||||||
// check for finished BOB protocol
|
// check for finished BOB protocol
|
||||||
if (mBOBState == bsCleared) {
|
if (mBOBState == bsCleared) {
|
||||||
// done
|
// done
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController waitForBob: mBOBState == bsCleared");
|
RS_DBG4("waitForBob: mBOBState == bsCleared");
|
||||||
mState = csDoDisconnect;
|
mState = csDoDisconnect;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case csDoDisconnect:
|
case csDoDisconnect:
|
||||||
if (!disconnectI2P() || mSocket != 0) {
|
if (!disconnectI2P() || mSocket != 0) {
|
||||||
// just in case
|
// just in case
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController doDisconnect: can't disconnect");
|
RS_DBG("doDisconnect: can't disconnect");
|
||||||
mStateOld = mState;
|
mStateOld = mState;
|
||||||
mState = csError;
|
mState = csError;
|
||||||
mErrorMsg = "unable to disconnect from BOB";
|
mErrorMsg = "unable to disconnect from BOB";
|
||||||
return sleepFactorDefault;
|
return sleepFactorDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController doDisconnect: disconnected");
|
RS_DBG4("doDisconnect: disconnected");
|
||||||
mState = csDisconnected;
|
mState = csDisconnected;
|
||||||
break;
|
break;
|
||||||
case csDisconnected:
|
case csDisconnected:
|
||||||
|
@ -487,12 +446,12 @@ int p3I2pBob::stateMachineController_locked_idle()
|
||||||
mProcessing = mPending.front();
|
mProcessing = mPending.front();
|
||||||
mPending.pop();
|
mPending.pop();
|
||||||
|
|
||||||
if (!mSetting.enableBob && (
|
if (!mSetting.enable && (
|
||||||
mProcessing->task == autoProxyTask::start ||
|
mProcessing->task == autoProxyTask::start ||
|
||||||
mProcessing->task == autoProxyTask::stop ||
|
mProcessing->task == autoProxyTask::stop ||
|
||||||
mProcessing->task == autoProxyTask::proxyStatusCheck)) {
|
mProcessing->task == autoProxyTask::proxyStatusCheck)) {
|
||||||
// skip since we are not enabled
|
// 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);
|
rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::disabled);
|
||||||
mProcessing = NULL;
|
mProcessing = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -514,7 +473,7 @@ int p3I2pBob::stateMachineController_locked_idle()
|
||||||
mTask = ctRunCheck;
|
mTask = ctRunCheck;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rslog(RsLog::Debug_Alert, &i2pBobLogInfo, "stateMachineController_locked_idle unknown async task");
|
RS_DBG1("unknown async task");
|
||||||
rsAutoProxyMonitor::taskError(mProcessing);
|
rsAutoProxyMonitor::taskError(mProcessing);
|
||||||
mProcessing = NULL;
|
mProcessing = NULL;
|
||||||
break;
|
break;
|
||||||
|
@ -561,29 +520,29 @@ int p3I2pBob::stateMachineController_locked_connected()
|
||||||
switch (mTask) {
|
switch (mTask) {
|
||||||
case ctRunSetUp:
|
case ctRunSetUp:
|
||||||
// when we have a key use it for server tunnel!
|
// when we have a key use it for server tunnel!
|
||||||
if(mSetting.keys.empty()) {
|
if(mSetting.address.privateKey.empty()) {
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickC");
|
RS_DBG4("setting mBOBState = setnickC");
|
||||||
mBOBState = bsSetnickC;
|
mBOBState = bsSetnickC;
|
||||||
} else {
|
} else {
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickS");
|
RS_DBG4("setting mBOBState = setnickS");
|
||||||
mBOBState = bsSetnickS;
|
mBOBState = bsSetnickS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ctRunShutDown:
|
case ctRunShutDown:
|
||||||
// shut down existing tunnel
|
// shut down existing tunnel
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = getnick");
|
RS_DBG4("setting mBOBState = getnick");
|
||||||
mBOBState = bsGetnick;
|
mBOBState = bsGetnick;
|
||||||
break;
|
break;
|
||||||
case ctRunCheck:
|
case ctRunCheck:
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = list");
|
RS_DBG4("setting mBOBState = list");
|
||||||
mBOBState = bsList;
|
mBOBState = bsList;
|
||||||
break;
|
break;
|
||||||
case ctRunGetKeys:
|
case ctRunGetKeys:
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_connected: setting mBOBState = setnickN");
|
RS_DBG4("setting mBOBState = setnickN");
|
||||||
mBOBState = bsSetnickN;
|
mBOBState = bsSetnickN;
|
||||||
break;
|
break;
|
||||||
case ctIdle:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +558,7 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||||
if(errorHappened) {
|
if(errorHappened) {
|
||||||
// reset old state
|
// reset old state
|
||||||
mStateOld = csIdel;
|
mStateOld = csIdel;
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_disconnected: error during process!");
|
RS_DBG("error during process!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// answer ticket
|
// answer ticket
|
||||||
|
@ -628,12 +587,12 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||||
mTask = mTaskOld;
|
mTask = mTaskOld;
|
||||||
|
|
||||||
if (!errorHappened) {
|
if (!errorHappened) {
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_disconnected: run check result: ok");
|
RS_DBG4("run check result: ok");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// switch to error
|
// switch to error
|
||||||
newState = csError;
|
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.";
|
mErrorMsg = "Connection check failed. Will try to restart tunnel.";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -656,7 +615,7 @@ int p3I2pBob::stateMachineController_locked_disconnected()
|
||||||
mTask = mTaskOld;
|
mTask = mTaskOld;
|
||||||
break;
|
break;
|
||||||
case ctIdle:
|
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);
|
rsAutoProxyMonitor::taskError(mProcessing);
|
||||||
}
|
}
|
||||||
mProcessing = NULL;
|
mProcessing = NULL;
|
||||||
|
@ -672,14 +631,12 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
{
|
{
|
||||||
// wait for bob protocoll
|
// wait for bob protocoll
|
||||||
if (mBOBState != bsCleared) {
|
if (mBOBState != bsCleared) {
|
||||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, "stateMachineController_locked_error: waiting for BOB");
|
RS_DBG4("waiting for BOB");
|
||||||
return sleepFactorFast;
|
return sleepFactorFast;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
std::stringstream ss;
|
RS_DBG4("stateMachineController_locked_error: mProcessing: ", (mProcessing ? "not null" : "null"));
|
||||||
ss << "stateMachineController_locked_error: mProcessing: " << (mProcessing ? "not null" : "null");
|
|
||||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// try to finish ticket
|
// try to finish ticket
|
||||||
|
@ -687,7 +644,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
switch (mTask) {
|
switch (mTask) {
|
||||||
case ctRunCheck:
|
case ctRunCheck:
|
||||||
// connection check failed at some point
|
// 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;
|
*((bool *)mProcessing->data) = true;
|
||||||
mState = csDoDisconnect;
|
mState = csDoDisconnect;
|
||||||
mStateOld = csIdel;
|
mStateOld = csIdel;
|
||||||
|
@ -695,7 +652,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
break;
|
break;
|
||||||
case ctRunShutDown:
|
case ctRunShutDown:
|
||||||
// not a big deal though
|
// 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;
|
mState = csDoDisconnect;
|
||||||
mStateOld = csIdel;
|
mStateOld = csIdel;
|
||||||
mErrorMsg.clear();
|
mErrorMsg.clear();
|
||||||
|
@ -703,14 +660,14 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
case ctIdle:
|
case ctIdle:
|
||||||
// should not happen but we need to deal with it
|
// 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)
|
// 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;
|
mState = csDoDisconnect;
|
||||||
mStateOld = csIdel;
|
mStateOld = csIdel;
|
||||||
mErrorMsg.clear();
|
mErrorMsg.clear();
|
||||||
break;
|
break;
|
||||||
case ctRunGetKeys:
|
case ctRunGetKeys:
|
||||||
case ctRunSetUp:
|
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;
|
mStateOld = csError;
|
||||||
mState = csDoDisconnect;
|
mState = csDoDisconnect;
|
||||||
// keep the error message
|
// keep the error message
|
||||||
|
@ -721,7 +678,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
|
|
||||||
// periodically retry
|
// periodically retry
|
||||||
if (mLastProxyCheck < time(NULL) - (selfCheckPeroid >> 1) && mTask == ctRunSetUp) {
|
if (mLastProxyCheck < time(NULL) - (selfCheckPeroid >> 1) && mTask == ctRunSetUp) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "stateMachineController_locked_error: retrying");
|
RS_DBG("retrying");
|
||||||
|
|
||||||
mLastProxyCheck = time(NULL);
|
mLastProxyCheck = time(NULL);
|
||||||
mErrorMsg.clear();
|
mErrorMsg.clear();
|
||||||
|
@ -734,7 +691,7 @@ int p3I2pBob::stateMachineController_locked_error()
|
||||||
|
|
||||||
// check for new tickets
|
// check for new tickets
|
||||||
if (!mPending.empty()) {
|
if (!mPending.empty()) {
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "stateMachineController_locked_error: processing new ticket");
|
RS_DBG4("processing new ticket");
|
||||||
|
|
||||||
// reset and try new task
|
// reset and try new task
|
||||||
mTask = ctIdle;
|
mTask = ctIdle;
|
||||||
|
@ -765,16 +722,16 @@ RsSerialiser *p3I2pBob::setupSerialiser()
|
||||||
|
|
||||||
bool p3I2pBob::saveList(bool &cleanup, std::list<RsItem *> &lst)
|
bool p3I2pBob::saveList(bool &cleanup, std::list<RsItem *> &lst)
|
||||||
{
|
{
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "saveList");
|
RS_DBG4("");
|
||||||
|
|
||||||
cleanup = true;
|
cleanup = true;
|
||||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet;
|
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet;
|
||||||
RsTlvKeyValue kv;
|
RsTlvKeyValue kv;
|
||||||
|
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enableBob ? "TRUE" : "FALSE")
|
addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enable ? "TRUE" : "FALSE")
|
||||||
addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.keys)
|
addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.address.privateKey)
|
||||||
addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.addr)
|
addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.address.base32)
|
||||||
addKVSInt(vitem, kv, kConfigKeyInLength, mSetting.inLength)
|
addKVSInt(vitem, kv, kConfigKeyInLength, mSetting.inLength)
|
||||||
addKVSInt(vitem, kv, kConfigKeyInQuantity, mSetting.inQuantity)
|
addKVSInt(vitem, kv, kConfigKeyInQuantity, mSetting.inQuantity)
|
||||||
addKVSInt(vitem, kv, kConfigKeyInVariance, mSetting.inVariance)
|
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)
|
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) {
|
for(std::list<RsItem*>::const_iterator it = load.begin(); it!=load.end(); ++it) {
|
||||||
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet*>(*it);
|
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet*>(*it);
|
||||||
|
@ -808,11 +765,11 @@ bool p3I2pBob::loadList(std::list<RsItem *> &load)
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) {
|
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) {
|
||||||
if (kit->key == kConfigKeyBOBEnable)
|
if (kit->key == kConfigKeyBOBEnable)
|
||||||
mSetting.enableBob = kit->value == "TRUE";
|
mSetting.enable = kit->value == "TRUE";
|
||||||
else if (kit->key == kConfigKeyBOBKey)
|
else if (kit->key == kConfigKeyBOBKey)
|
||||||
mSetting.keys = kit->value;
|
mSetting.address.privateKey = kit->value;
|
||||||
else if (kit->key == kConfigKeyBOBAddr)
|
else if (kit->key == kConfigKeyBOBAddr)
|
||||||
mSetting.addr = kit->value;
|
mSetting.address.base32 = kit->value;
|
||||||
getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength)
|
getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength)
|
||||||
getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity)
|
getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity)
|
||||||
getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance)
|
getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance)
|
||||||
|
@ -820,7 +777,7 @@ bool p3I2pBob::loadList(std::list<RsItem *> &load)
|
||||||
getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity)
|
getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity)
|
||||||
getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance)
|
getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance)
|
||||||
else
|
else
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "loadList unknown key: " + kit->key);
|
RS_DBG("unknown key: ", kit->key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete vitem;
|
delete vitem;
|
||||||
|
@ -884,7 +841,7 @@ void p3I2pBob::getStates(bobStates *bs)
|
||||||
|
|
||||||
std::string p3I2pBob::executeCommand(const std::string &command)
|
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;
|
std::string copy = command;
|
||||||
copy.push_back('\n');
|
copy.push_back('\n');
|
||||||
|
@ -896,7 +853,7 @@ std::string p3I2pBob::executeCommand(const std::string &command)
|
||||||
// receive answer (trailing new line is already removed!)
|
// receive answer (trailing new line is already removed!)
|
||||||
std::string ans = recv();
|
std::string ans = recv();
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "executeCommand_locked answer '" + ans + "'");
|
RS_DBG4("answer: ", ans);
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
@ -906,7 +863,7 @@ bool p3I2pBob::connectI2P()
|
||||||
// there is only one thread that touches mSocket - no need for a lock
|
// there is only one thread that touches mSocket - no need for a lock
|
||||||
|
|
||||||
if (mSocket != 0) {
|
if (mSocket != 0) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked mSocket != 0");
|
RS_DBG("mSocket != 0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,21 +871,21 @@ bool p3I2pBob::connectI2P()
|
||||||
mSocket = unix_socket(PF_INET, SOCK_STREAM, 0);
|
mSocket = unix_socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (mSocket < 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect
|
// connect
|
||||||
int err = unix_connect(mSocket, mI2PProxyAddr);
|
int err = unix_connect(mSocket, mI2PProxyAddr);
|
||||||
if (err != 0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// receive hello msg
|
// receive hello msg
|
||||||
recv();
|
recv();
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "connectI2P_locked done");
|
RS_DBG4("done");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,17 +894,17 @@ bool p3I2pBob::disconnectI2P()
|
||||||
// there is only one thread that touches mSocket - no need for a lock
|
// there is only one thread that touches mSocket - no need for a lock
|
||||||
|
|
||||||
if (mSocket == 0) {
|
if (mSocket == 0) {
|
||||||
rslog(RsLog::Warning, &i2pBobLogInfo, "disconnectI2P_locked mSocket == 0");
|
RS_DBG("mSocket == 0");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = unix_close(mSocket);
|
int err = unix_close(mSocket);
|
||||||
if (err != 0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "disconnectI2P_locked done");
|
RS_DBG4("done");
|
||||||
mSocket = 0;
|
mSocket = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -968,7 +925,7 @@ std::string toString(const std::string &a, const int8_t b) {
|
||||||
|
|
||||||
void p3I2pBob::finalizeSettings_locked()
|
void p3I2pBob::finalizeSettings_locked()
|
||||||
{
|
{
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked");
|
RS_DBG4("");
|
||||||
|
|
||||||
sockaddr_storage_clear(mI2PProxyAddr);
|
sockaddr_storage_clear(mI2PProxyAddr);
|
||||||
// get i2p proxy addr
|
// get i2p proxy addr
|
||||||
|
@ -979,8 +936,8 @@ void p3I2pBob::finalizeSettings_locked()
|
||||||
sockaddr_storage_setipv4(mI2PProxyAddr, (sockaddr_in*)&proxy);
|
sockaddr_storage_setipv4(mI2PProxyAddr, (sockaddr_in*)&proxy);
|
||||||
sockaddr_storage_setport(mI2PProxyAddr, 2827);
|
sockaddr_storage_setport(mI2PProxyAddr, 2827);
|
||||||
|
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked using " + sockaddr_storage_tostring(mI2PProxyAddr));
|
RS_DBG4("using ", mI2PProxyAddr);
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "finalizeSettings_locked using " + mSetting.addr);
|
RS_DBG4("using ", mSetting.address.base32);
|
||||||
|
|
||||||
peerState ps;
|
peerState ps;
|
||||||
mPeerMgr->getOwnNetStatus(ps);
|
mPeerMgr->getOwnNetStatus(ps);
|
||||||
|
@ -988,21 +945,17 @@ void p3I2pBob::finalizeSettings_locked()
|
||||||
// setup commands
|
// setup commands
|
||||||
// new lines are appended later!
|
// new lines are appended later!
|
||||||
|
|
||||||
// generate random suffix for name
|
// generate 8 characater long random suffix for name
|
||||||
// RSRandom::random_alphaNumericString can return very weird looking strings like: ,,@z+M
|
constexpr size_t len = 8;
|
||||||
// use base32 instead
|
const std::string location = RsRandom::alphaNumeric(len);
|
||||||
size_t len = 5; // 5 characters = 8 base32 symbols
|
RS_DBG4("using suffix ", location);
|
||||||
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);
|
|
||||||
mTunnelName = "RetroShare-" + location;
|
mTunnelName = "RetroShare-" + location;
|
||||||
|
|
||||||
const std::string setnick = "setnick RetroShare-" + location;
|
const std::string setnick = "setnick RetroShare-" + location;
|
||||||
const std::string getnick = "getnick RetroShare-" + location;
|
const std::string getnick = "getnick RetroShare-" + location;
|
||||||
const std::string newkeys = "newkeys";
|
const std::string newkeys = "newkeys";
|
||||||
const std::string getkeys = "getkeys";
|
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 inhost = "inhost " + sockaddr_storage_iptostring(proxy);
|
||||||
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
||||||
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
||||||
|
@ -1063,7 +1016,7 @@ void p3I2pBob::finalizeSettings_locked()
|
||||||
|
|
||||||
void p3I2pBob::updateSettings_locked()
|
void p3I2pBob::updateSettings_locked()
|
||||||
{
|
{
|
||||||
rslog(RsLog::Debug_Basic, &i2pBobLogInfo, "updateSettings_locked");
|
RS_DBG4("");
|
||||||
|
|
||||||
sockaddr_storage proxy;
|
sockaddr_storage proxy;
|
||||||
mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy);
|
mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy);
|
||||||
|
@ -1071,7 +1024,7 @@ void p3I2pBob::updateSettings_locked()
|
||||||
peerState ps;
|
peerState ps;
|
||||||
mPeerMgr->getOwnNetStatus(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 inhost = "inhost " + sockaddr_storage_iptostring(proxy);
|
||||||
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
const std::string inport = toString("inport ", sockaddr_storage_port(proxy));
|
||||||
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr);
|
||||||
|
@ -1103,38 +1056,62 @@ void p3I2pBob::updateSettings_locked()
|
||||||
|
|
||||||
std::string p3I2pBob::recv()
|
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;
|
std::string ans;
|
||||||
ssize_t length;
|
uint16_t retry = 10;
|
||||||
const uint16_t bufferSize = 128;
|
|
||||||
std::vector<char> buffer(bufferSize);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
memset(buffer, 0, bufferSize);
|
||||||
|
|
||||||
|
// peek at data
|
||||||
|
auto length = ::recv(mSocket, buffer, bufferSize, MSG_PEEK);
|
||||||
|
if (length <= 0) {
|
||||||
|
if (length < 0) {
|
||||||
|
// error
|
||||||
|
perror(__PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
retry--;
|
||||||
doSleep(sleepTimeRecv);
|
doSleep(sleepTimeRecv);
|
||||||
|
|
||||||
// there is only one thread that touches mSocket - no need for a lock
|
|
||||||
length = ::recv(mSocket, buffer.data(), buffer.size(), 0);
|
|
||||||
if (length < 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ans.append(buffer.begin(), buffer.end());
|
// at least one byte was read
|
||||||
|
|
||||||
// clean received string
|
// search for new line
|
||||||
ans.erase(std::remove(ans.begin(), ans.end(), '\0'), ans.end());
|
auto bufferStr = std::string(buffer);
|
||||||
ans.erase(std::remove(ans.begin(), ans.end(), '\n'), ans.end());
|
size_t pos = bufferStr.find('\n');
|
||||||
|
|
||||||
#if 0
|
if (pos == std::string::npos) {
|
||||||
std::stringstream ss;
|
// no new line found -> more to read
|
||||||
ss << "recv length: " << length << " (bufferSize: " << bufferSize << ") ans: " << ans.length();
|
|
||||||
rslog(RsLog::Debug_All, &i2pBobLogInfo, ss.str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// clear and resize buffer again
|
// sanity check
|
||||||
buffer.clear();
|
if (length != bufferSize) {
|
||||||
buffer.resize(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())
|
// calculate how much there is to read, read the \n, too!
|
||||||
break;
|
length = pos + 1;
|
||||||
} while(length == bufferSize || ans.size() < 4);
|
|
||||||
|
// 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;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,10 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "pqi/p3cfgmgr.h"
|
||||||
#include "services/autoproxy/rsautoproxymonitor.h"
|
#include "services/autoproxy/rsautoproxymonitor.h"
|
||||||
#include "util/rsthreads.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
|
* This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
*
|
*
|
||||||
* Note 3:
|
* Note 3:
|
||||||
* BOB needs a unique name as an ID for each tunnel.
|
* 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:
|
* Design:
|
||||||
* The service uses three state machines to manage its task:
|
* The service uses three state machines to manage its task:
|
||||||
|
@ -72,7 +73,7 @@
|
||||||
* mCommands[bobState::quit] = {quit, bobState::cleared};
|
* mCommands[bobState::quit] = {quit, bobState::cleared};
|
||||||
*
|
*
|
||||||
* stateMachineController:
|
* stateMachineController:
|
||||||
* This state machone manages the high level tasks.
|
* This state machine manages the high level tasks.
|
||||||
* It is controlled by mState and mTask.
|
* It is controlled by mState and mTask.
|
||||||
*
|
*
|
||||||
* mTast:
|
* mTast:
|
||||||
|
@ -162,19 +163,7 @@ struct bobStateInfo {
|
||||||
bobState nextState;
|
bobState nextState;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bobSettings {
|
struct bobSettings : i2p::settings {};
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief The bobStates struct
|
/// \brief The bobStates struct
|
||||||
|
@ -203,8 +192,6 @@ public:
|
||||||
void processTaskAsync(taskTicket *ticket);
|
void processTaskAsync(taskTicket *ticket);
|
||||||
void processTaskSync(taskTicket *ticket);
|
void processTaskSync(taskTicket *ticket);
|
||||||
|
|
||||||
static std::string keyToBase32Addr(const std::string &key);
|
|
||||||
|
|
||||||
void threadTick() override; /// @see RsTickingThread
|
void threadTick() override; /// @see RsTickingThread
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "rsautoproxymonitor.h"
|
#include "rsautoproxymonitor.h"
|
||||||
|
|
||||||
#include <unistd.h> /* for usleep() */
|
#include <unistd.h> /* for usleep() */
|
||||||
|
#include "util/rsdebug.h"
|
||||||
#include "util/rstime.h"
|
#include "util/rstime.h"
|
||||||
|
|
||||||
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
|
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
|
||||||
|
@ -42,8 +43,10 @@ rsAutoProxyMonitor *rsAutoProxyMonitor::instance()
|
||||||
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
|
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mLock);
|
RS_STACK_MUTEX(mLock);
|
||||||
if (mProxies.find(type) != mProxies.end())
|
if (mProxies.find(type) != mProxies.end()) {
|
||||||
std::cerr << "sAutoProxyMonitor::addProxy type " << type << " already added - OVERWRITING" << std::endl;
|
RS_ERR("type ", type, " already added - OVERWRITING");
|
||||||
|
print_stacktrace();
|
||||||
|
}
|
||||||
|
|
||||||
mProxies[type] = service;
|
mProxies[type] = service;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +120,7 @@ void rsAutoProxyMonitor::stopAllRSShutdown()
|
||||||
do {
|
do {
|
||||||
rstime::rs_usleep(1000 * 1000);
|
rstime::rs_usleep(1000 * 1000);
|
||||||
RS_STACK_MUTEX(mLock);
|
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())
|
if (mProxies.empty())
|
||||||
break;
|
break;
|
||||||
t++;
|
t++;
|
||||||
|
@ -146,13 +149,16 @@ void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||||
{
|
{
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if (!ticket->async && ticket->types.size() > 1) {
|
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) {
|
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) {
|
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;
|
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it;
|
||||||
|
@ -168,7 +174,11 @@ void rsAutoProxyMonitor::task(taskTicket *ticket)
|
||||||
*tt = *ticket;
|
*tt = *ticket;
|
||||||
tt->types.clear();
|
tt->types.clear();
|
||||||
tt->types.push_back(*it);
|
tt->types.push_back(*it);
|
||||||
|
|
||||||
|
// it's async!
|
||||||
|
RsThread::async([s, tt] {
|
||||||
s->processTaskAsync(tt);
|
s->processTaskAsync(tt);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
s->processTaskSync(ticket);
|
s->processTaskSync(ticket);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +197,8 @@ void rsAutoProxyMonitor::taskAsync(std::vector<autoProxyType::autoProxyType_enum
|
||||||
if (!isAsyncTask(task)) {
|
if (!isAsyncTask(task)) {
|
||||||
// Usually the services will reject this ticket.
|
// Usually the services will reject this ticket.
|
||||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
// 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();
|
taskTicket *tt = getTicket();
|
||||||
|
@ -215,7 +226,8 @@ void rsAutoProxyMonitor::taskSync(std::vector<autoProxyType::autoProxyType_enum>
|
||||||
if (isAsyncTask(task)) {
|
if (isAsyncTask(task)) {
|
||||||
// Usually the services will reject this ticket.
|
// Usually the services will reject this ticket.
|
||||||
// Just print a warning - maybe there is some special case where this is a good idea.
|
// 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();
|
taskTicket *tt = getTicket();
|
||||||
|
@ -244,7 +256,8 @@ void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatu
|
||||||
t->cb->taskFinished(t);
|
t->cb->taskFinished(t);
|
||||||
if (t != NULL) {
|
if (t != NULL) {
|
||||||
// callack did not clean up properly
|
// 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;
|
cleanUp = true;
|
||||||
}
|
}
|
||||||
} else if (t->async){
|
} else if (t->async){
|
||||||
|
@ -252,12 +265,13 @@ void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatu
|
||||||
// we must take care of deleting
|
// we must take care of deleting
|
||||||
cleanUp = true;
|
cleanUp = true;
|
||||||
if(t->data)
|
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 (cleanUp) {
|
||||||
if (t->data) {
|
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 push
|
||||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||||
delete t->data;
|
delete t->data;
|
||||||
|
@ -290,7 +304,8 @@ void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket)
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
if (ticket->data) {
|
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 push
|
||||||
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
|
||||||
delete ticket->data;
|
delete ticket->data;
|
||||||
|
@ -308,7 +323,7 @@ autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType
|
||||||
if ((itService = mProxies.find(t)) != mProxies.end()) {
|
if ((itService = mProxies.find(t)) != mProxies.end()) {
|
||||||
return itService->second;
|
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;
|
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.hiddenport_spinBox->setVisible(hidden_state && !tor_auto);
|
||||||
|
|
||||||
ui.cbUseBob->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)
|
if(!mAllFieldsOk)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <gui/notifyqt.h>
|
#include <gui/notifyqt.h>
|
||||||
#include "rshare.h"
|
#include "rshare.h"
|
||||||
#include "rsharesettings.h"
|
#include "rsharesettings.h"
|
||||||
|
#include "util/i2pcommon.h"
|
||||||
#include "util/RsNetUtil.h"
|
#include "util/RsNetUtil.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
|
|
||||||
|
@ -82,6 +83,10 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
|
||||||
manager = NULL ;
|
manager = NULL ;
|
||||||
mOngoingConnectivityCheck = -1;
|
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::isHiddenNode())
|
||||||
{
|
{
|
||||||
if(RsAccounts::isTorAuto())
|
if(RsAccounts::isTorAuto())
|
||||||
|
@ -1352,7 +1357,7 @@ void ServerPage::updateInProxyIndicator()
|
||||||
ui.iconlabel_service_incoming->setMovie(movie);
|
ui.iconlabel_service_incoming->setMovie(movie);
|
||||||
movie->start();
|
movie->start();
|
||||||
|
|
||||||
if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enableBob) {
|
if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enable) {
|
||||||
|
|
||||||
QTcpSocket tcpSocket;
|
QTcpSocket tcpSocket;
|
||||||
|
|
||||||
|
@ -1439,15 +1444,16 @@ void ServerPage::getNewKey()
|
||||||
|
|
||||||
void ServerPage::loadKey()
|
void ServerPage::loadKey()
|
||||||
{
|
{
|
||||||
mBobSettings.keys = ui.pteBobServerKey->toPlainText().toStdString();
|
mBobSettings.address.privateKey = ui.pteBobServerKey->toPlainText().toStdString();
|
||||||
mBobSettings.addr = p3I2pBob::keyToBase32Addr(mBobSettings.keys);
|
mBobSettings.address.publicKey = i2p::publicKeyFromPrivate(mBobSettings.address.privateKey);
|
||||||
|
mBobSettings.address.base32 = i2p::keyToBase32Addr(mBobSettings.address.publicKey);
|
||||||
|
|
||||||
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerPage::enableBob(bool checked)
|
void ServerPage::enableBob(bool checked)
|
||||||
{
|
{
|
||||||
mBobSettings.enableBob = checked;
|
mBobSettings.enable = checked;
|
||||||
|
|
||||||
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings);
|
||||||
|
|
||||||
|
@ -1487,7 +1493,7 @@ void ServerPage::toggleBobAdvancedSettings(bool checked)
|
||||||
{
|
{
|
||||||
ui.swBobAdvanced->setCurrentIndex(checked ? 1 : 0);
|
ui.swBobAdvanced->setCurrentIndex(checked ? 1 : 0);
|
||||||
|
|
||||||
if (!mBobSettings.keys.empty()) {
|
if (!mBobSettings.address.privateKey.empty()) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
ui.pbBobGenAddr->show();
|
ui.pbBobGenAddr->show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1578,9 +1584,9 @@ void ServerPage::loadCommon()
|
||||||
whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab
|
whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab
|
||||||
|
|
||||||
// don't use whileBlocking here
|
// 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.lBobB32Addr->show();
|
||||||
ui.leBobB32Addr->show();
|
ui.leBobB32Addr->show();
|
||||||
}
|
}
|
||||||
|
@ -1623,13 +1629,13 @@ void ServerPage::saveBob()
|
||||||
|
|
||||||
void ServerPage::updateStatusBob()
|
void ServerPage::updateStatusBob()
|
||||||
{
|
{
|
||||||
QString addr = QString::fromStdString(mBobSettings.addr);
|
QString addr = QString::fromStdString(mBobSettings.address.base32);
|
||||||
if (ui.leBobB32Addr->text() != addr) {
|
if (ui.leBobB32Addr->text() != addr) {
|
||||||
ui.leBobB32Addr->setText(addr);
|
ui.leBobB32Addr->setText(addr);
|
||||||
ui.hiddenpage_serviceAddress->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
|
// we have an addr -> show fields
|
||||||
ui.lBobB32Addr->show();
|
ui.lBobB32Addr->show();
|
||||||
ui.leBobB32Addr->show();
|
ui.leBobB32Addr->show();
|
||||||
|
@ -1655,7 +1661,7 @@ void ServerPage::updateStatusBob()
|
||||||
QString bobSimpleText = QString();
|
QString bobSimpleText = QString();
|
||||||
bobSimpleText.append(tr("RetroShare uses BOB to set up a %1 tunnel at %2:%3 (named %4)\n\n"
|
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").
|
"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_proxyAddress_i2p_2->text(),
|
||||||
ui.hiddenpage_proxyPort_i2p_2->text(),
|
ui.hiddenpage_proxyPort_i2p_2->text(),
|
||||||
bs.tunnelName.empty() ? tr("unknown") :
|
bs.tunnelName.empty() ? tr("unknown") :
|
||||||
|
@ -1777,15 +1783,15 @@ void ServerPage::updateStatusBob()
|
||||||
|
|
||||||
void ServerPage::setUpBobElements()
|
void ServerPage::setUpBobElements()
|
||||||
{
|
{
|
||||||
ui.gbBob->setEnabled(mBobSettings.enableBob);
|
ui.gbBob->setEnabled(mBobSettings.enable);
|
||||||
if (mBobSettings.enableBob) {
|
if (mBobSettings.enable) {
|
||||||
ui.hiddenpage_proxyAddress_i2p->setEnabled(false);
|
ui.hiddenpage_proxyAddress_i2p->setEnabled(false);
|
||||||
ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
||||||
ui.hiddenpage_proxyPort_i2p->setEnabled(false);
|
ui.hiddenpage_proxyPort_i2p->setEnabled(false);
|
||||||
ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P/BOB settings to change this value");
|
||||||
|
|
||||||
ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.addr));
|
ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.address.base32));
|
||||||
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.keys));
|
ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey));
|
||||||
|
|
||||||
// cast to int to avoid problems
|
// cast to int to avoid problems
|
||||||
int li, lo, qi, qo, vi, vo;
|
int li, lo, qi, qo, vi, vo;
|
||||||
|
|
|
@ -140,6 +140,11 @@ rs_macos10.15:CONFIG -= rs_macos10.11
|
||||||
CONFIG *= no_rs_jsonapi
|
CONFIG *= no_rs_jsonapi
|
||||||
rs_jsonapi: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
|
# To enable channel indexing append the following assignation to qmake command
|
||||||
# line "CONFIG+=rs_deep_channel_index"
|
# line "CONFIG+=rs_deep_channel_index"
|
||||||
CONFIG *= no_rs_deep_channel_index
|
CONFIG *= no_rs_deep_channel_index
|
||||||
|
@ -550,6 +555,10 @@ rs_webui {
|
||||||
DEFINES *= RS_WEBUI
|
DEFINES *= RS_WEBUI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs_bob {
|
||||||
|
DEFINES *= RS_USE_I2P_BOB
|
||||||
|
}
|
||||||
|
|
||||||
rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX
|
rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX
|
||||||
|
|
||||||
rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX
|
rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue