mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-24 08:50:10 -05:00
262 lines
6.1 KiB
C++
262 lines
6.1 KiB
C++
#include "pqissli2psam3.h"
|
|
|
|
#include <libsam3.h>
|
|
|
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
|
|
|
static constexpr int pqiDone = 1;
|
|
static constexpr int pqiWait = 0;
|
|
static constexpr int pqiError = -1;
|
|
|
|
pqissli2psam3::pqissli2psam3(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
|
|
: pqissl(l, parent, lm), mState(pqisslSam3State::NONE), mI2pAddrB32(), mI2pAddrLong()
|
|
{
|
|
RS_DBG4();
|
|
mConn = nullptr;
|
|
}
|
|
|
|
bool pqissli2psam3::connect_parameter(uint32_t type, const std::string &value)
|
|
{
|
|
RS_DBG4();
|
|
|
|
if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS)
|
|
{
|
|
RS_DBG1("got addr:", value);
|
|
RS_STACK_MUTEX(mSslMtx);
|
|
mI2pAddrB32 = value;
|
|
return true;
|
|
}
|
|
|
|
return pqissl::connect_parameter(type, value);
|
|
}
|
|
|
|
int pqissli2psam3::Initiate_Connection()
|
|
{
|
|
RS_DBG4();
|
|
|
|
if(waiting != WAITING_DELAY)
|
|
{
|
|
RS_ERR("Already Attempt in Progress!");
|
|
return pqiError;
|
|
}
|
|
|
|
switch (mState) {
|
|
case(pqisslSam3State::NONE):
|
|
RS_DBG2("NONE");
|
|
{
|
|
if(mConn) {
|
|
// how did we end up here?
|
|
RS_ERR("state is NONE but a connection is existing?!");
|
|
}
|
|
mConn = 0;
|
|
// get SAM session
|
|
mConn = 0;
|
|
samSettings ss;
|
|
ss.session = nullptr;
|
|
rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, static_cast<void*>(&ss));
|
|
|
|
if (!!ss.session) {
|
|
RS_DBG3("NONE->DO_LOOKUP");
|
|
mState = pqisslSam3State::DO_LOOKUP;
|
|
} else {
|
|
RS_DBG3("NONE->DO_LOOKUP NOPE", ss.session);
|
|
}
|
|
}
|
|
break;
|
|
case(pqisslSam3State::DO_LOOKUP):
|
|
RS_DBG1("DO_LOOKUP");
|
|
|
|
if (!mI2pAddrLong.empty()) {
|
|
// skip lookup, it is highly unlikely/impossible for a public key to change (isn't it?)
|
|
mState = pqisslSam3State::WAIT_LOOKUP;
|
|
break;
|
|
}
|
|
|
|
{
|
|
i2p::address *addr = new i2p::address;
|
|
addr->clear();
|
|
addr->base32 = mI2pAddrB32;
|
|
rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::lookupKey, this, static_cast<void*>(addr));
|
|
}
|
|
mState = pqisslSam3State::WAIT_LOOKUP;
|
|
break;
|
|
case(pqisslSam3State::DO_CONNECT):
|
|
RS_DBG2("DO_CONNECT");
|
|
|
|
{
|
|
auto wrapper = new samEstablishConnectionWrapper();
|
|
wrapper->address.clear();
|
|
wrapper->address.publicKey = mI2pAddrLong;
|
|
wrapper->connection = nullptr;
|
|
|
|
rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::establishConnection, this, static_cast<void*>(wrapper));
|
|
}
|
|
mState = pqisslSam3State::WAIT_CONNECT;
|
|
break;
|
|
case(pqisslSam3State::DONE):
|
|
RS_DBG2("DONE");
|
|
|
|
if (setupSocket())
|
|
return pqiDone;
|
|
return pqiError;
|
|
|
|
/* waiting */
|
|
case(pqisslSam3State::WAIT_LOOKUP):
|
|
RS_DBG3("WAIT_LOOKUP");
|
|
break;
|
|
case(pqisslSam3State::WAIT_CONNECT):
|
|
RS_DBG3("WAIT_CONNECT");
|
|
break;
|
|
}
|
|
return pqiWait;
|
|
}
|
|
|
|
int pqissli2psam3::net_internal_close(int fd)
|
|
{
|
|
RS_DBG4();
|
|
|
|
// sanity check
|
|
if (mConn && fd != mConn->fd) {
|
|
// this should never happen!
|
|
RS_ERR("fd != mConn");
|
|
// sam3CloseConnection(mConn);
|
|
}
|
|
|
|
// now to the actuall closing
|
|
int ret = pqissl::net_internal_close(fd);
|
|
|
|
rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::closeConnection, this, mConn);
|
|
|
|
// finally cleanup
|
|
mConn = 0;
|
|
mState = pqisslSam3State::NONE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void pqissli2psam3::taskFinished(taskTicket *&ticket)
|
|
{
|
|
RS_DBG4();
|
|
|
|
switch (ticket->task) {
|
|
case autoProxyTask::lookupKey:
|
|
{
|
|
auto addr = static_cast<i2p::address*>(ticket->data);
|
|
|
|
RS_STACK_MUTEX(mSslMtx);
|
|
if (ticket->result == autoProxyStatus::ok) {
|
|
mI2pAddrLong = addr->publicKey;
|
|
mState = pqisslSam3State::DO_CONNECT;
|
|
} else {
|
|
waiting = WAITING_FAIL_INTERFACE;
|
|
}
|
|
|
|
delete addr;
|
|
ticket->data = nullptr;
|
|
addr = nullptr;
|
|
}
|
|
break;
|
|
case autoProxyTask::establishConnection:
|
|
{
|
|
auto wrapper = static_cast<struct samEstablishConnectionWrapper*>(ticket->data);
|
|
|
|
RS_STACK_MUTEX(mSslMtx);
|
|
if (ticket->result == autoProxyStatus::ok) {
|
|
mConn = wrapper->connection;
|
|
mState = pqisslSam3State::DONE;
|
|
} else {
|
|
waiting = WAITING_FAIL_INTERFACE;
|
|
}
|
|
|
|
delete wrapper;
|
|
ticket->data = nullptr;
|
|
wrapper = nullptr;
|
|
}
|
|
break;
|
|
case autoProxyTask::closeConnection:
|
|
// nothing to do here
|
|
break;
|
|
default:
|
|
RS_WARN("unkown task", ticket->task);
|
|
}
|
|
|
|
// clean up!
|
|
delete ticket;
|
|
ticket = nullptr;
|
|
}
|
|
|
|
bool pqissli2psam3::setupSocket()
|
|
{
|
|
/*
|
|
* This function contains the generis part from pqissl::Initiate_Connection()
|
|
*/
|
|
int err;
|
|
int osock = mConn->fd;
|
|
|
|
err = unix_fcntl_nonblock(osock);
|
|
if (err < 0)
|
|
{
|
|
RS_ERR("Cannot make socket NON-Blocking:", err);
|
|
|
|
waiting = WAITING_FAIL_INTERFACE;
|
|
net_internal_close(osock);
|
|
return false;
|
|
}
|
|
|
|
#ifdef WINDOWS_SYS
|
|
/* Set TCP buffer size for Windows systems */
|
|
|
|
int sockbufsize = 0;
|
|
int size = sizeof(int);
|
|
|
|
err = getsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &size);
|
|
#ifdef PQISSL_DEBUG
|
|
if (err == 0) {
|
|
std::cerr << "pqissl::Initiate_Connection: Current TCP receive buffer size " << sockbufsize << std::endl;
|
|
} else {
|
|
std::cerr << "pqissl::Initiate_Connection: Error getting TCP receive buffer size. Error " << err << std::endl;
|
|
}
|
|
#endif
|
|
|
|
sockbufsize = 0;
|
|
|
|
err = getsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, &size);
|
|
#ifdef PQISSL_DEBUG
|
|
if (err == 0) {
|
|
std::cerr << "pqissl::Initiate_Connection: Current TCP send buffer size " << sockbufsize << std::endl;
|
|
} else {
|
|
std::cerr << "pqissl::Initiate_Connection: Error getting TCP send buffer size. Error " << err << std::endl;
|
|
}
|
|
#endif
|
|
|
|
sockbufsize = WINDOWS_TCP_BUFFER_SIZE;
|
|
|
|
err = setsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, sizeof(sockbufsize));
|
|
#ifdef PQISSL_DEBUG
|
|
if (err == 0) {
|
|
std::cerr << "pqissl::Initiate_Connection: TCP receive buffer size set to " << sockbufsize << std::endl;
|
|
} else {
|
|
std::cerr << "pqissl::Initiate_Connection: Error setting TCP receive buffer size. Error " << err << std::endl;
|
|
}
|
|
#endif
|
|
|
|
err = setsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, sizeof(sockbufsize));
|
|
#ifdef PQISSL_DEBUG
|
|
if (err == 0) {
|
|
std::cerr << "pqissl::Initiate_Connection: TCP send buffer size set to " << sockbufsize << std::endl;
|
|
} else {
|
|
std::cerr << "pqissl::Initiate_Connection: Error setting TCP send buffer size. Error " << err << std::endl;
|
|
}
|
|
#endif
|
|
#endif // WINDOWS_SYS
|
|
|
|
|
|
mTimeoutTS = time(NULL) + mConnectTimeout;
|
|
//std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl;
|
|
|
|
waiting = WAITING_SOCK_CONNECT;
|
|
sockfd = osock;
|
|
|
|
return true;
|
|
}
|