Significant changes to aid UDP connections.

* Added Period and Delay parameters to connections.
   - Delay is used to avoid simultaneous TCP connections.
   - Period is used to regulate UDP connections.
 * added Delay code to pqissl.
 * added Period code to tcponudp / pqissludp.
 * modified TTL modification code.
 * increased SynPktRetransmit value.
 * fixed retrans() timeout (one reason code wasn't working before!)
 * fixed tou_close() SEGV bug.
 * modified pqissludp tou_socket creation. (non permanent now).
 * Modified format of peerConnectRequest() CB to make it more useful and rewrote function.
 * Enabled pqissludp NetInterface.
 * using Id comparision to determine Active/Passive UDP connection state.
 * added #def to disable TCP connections. (for testing)
 * enabled UDP connections from retryConnect() function.
 * corrected EXT check in retryConnect() function.
 * + lots of debug output and other stuff.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@358 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-02-27 02:32:20 +00:00
parent e87b7b75e7
commit 8b230a55cf
24 changed files with 381 additions and 87 deletions

View File

@ -46,12 +46,16 @@ const uint32_t RS_STUN_LIST_MIN = 100;
const uint32_t MAX_UPNP_INIT = 60; /* seconds UPnP timeout */
#define CONN_DEBUG 1
#define P3CONNMGR_NO_TCP_CONNECTIONS 1
const uint32_t P3CONNMGR_TCP_DEFAULT_DELAY = 10; /* 10 Seconds should be enough! */
const uint32_t P3CONNMGR_UDP_DHT_DELAY = 300; /* 5 minutes */
const uint32_t P3CONNMGR_UDP_PROXY_DELAY = 30; /* 30 seconds */
void printConnectState(peerConnectState &peer);
peerConnectAddress::peerConnectAddress()
:type(0), ts(0)
:delay(0), period(0), type(0), ts(0)
{
sockaddr_clear(&addr);
}
@ -933,7 +937,9 @@ void p3ConnectMgr::getOthersList(std::list<std::string> &peers)
bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr, uint32_t &type)
bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr,
uint32_t &delay, uint32_t &period, uint32_t &type)
{
/* check for existing */
std::map<std::string, peerConnectState>::iterator it;
@ -963,6 +969,8 @@ bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr, uint
it->second.connAddrs.pop_front();
addr = it->second.currentConnAddr.addr;
delay = it->second.currentConnAddr.delay;
period = it->second.currentConnAddr.period;
type = it->second.currentConnAddr.type;
std::cerr << "p3ConnectMgr::connectAttempt() Success: ";
@ -970,6 +978,8 @@ bool p3ConnectMgr::connectAttempt(std::string id, struct sockaddr_in &addr, uint
std::cerr << std::endl;
std::cerr << " laddr: " << inet_ntoa(addr.sin_addr);
std::cerr << " lport: " << ntohs(addr.sin_port);
std::cerr << " delay: " << delay;
std::cerr << " period: " << period;
std::cerr << " type: " << type;
std::cerr << std::endl;
@ -1235,13 +1245,27 @@ void p3ConnectMgr::peerStatus(std::string id,
std::cerr << " flags: " << flags;
std::cerr << " source: " << source;
std::cerr << std::endl;
#ifndef P3CONNMGR_NO_TCP_CONNECTIONS
time_t now = time(NULL);
/* add in attempts ... local(TCP), remote(TCP)
* udp must come from notify
*/
/* determine delay (for TCP connections)
* this is to ensure that simultaneous connections don't occur
* (which can fail).
* easest way is to compare ids ... and delay one of them
*/
uint32_t tcp_delay = 0;
if (id > ownState.id)
{
tcp_delay = P3CONNMGR_TCP_DEFAULT_DELAY;
}
/* if address is same -> try local */
if ((isValidNet(&(details.laddr.sin_addr))) &&
(sameNet(&(ownState.localaddr.sin_addr), &(details.laddr.sin_addr))))
@ -1250,6 +1274,8 @@ void p3ConnectMgr::peerStatus(std::string id,
/* add the local address */
peerConnectAddress pca;
pca.ts = now;
pca.delay = tcp_delay;
pca.period = 0;
pca.type = RS_NET_CONN_TCP_LOCAL;
pca.addr = details.laddr;
@ -1257,6 +1283,8 @@ void p3ConnectMgr::peerStatus(std::string id,
std::cerr << " id: " << id;
std::cerr << " laddr: " << inet_ntoa(pca.addr.sin_addr);
std::cerr << " lport: " << ntohs(pca.addr.sin_port);
std::cerr << " delay: " << pca.delay;
std::cerr << " period: " << pca.period;
std::cerr << " type: " << pca.type;
std::cerr << " source: " << source;
std::cerr << std::endl;
@ -1282,6 +1310,8 @@ void p3ConnectMgr::peerStatus(std::string id,
/* add the remote address */
peerConnectAddress pca;
pca.ts = now;
pca.delay = tcp_delay;
pca.period = 0;
pca.type = RS_NET_CONN_TCP_EXTERNAL;
pca.addr = details.raddr;
@ -1289,6 +1319,8 @@ void p3ConnectMgr::peerStatus(std::string id,
std::cerr << " id: " << id;
std::cerr << " laddr: " << inet_ntoa(pca.addr.sin_addr);
std::cerr << " lport: " << ntohs(pca.addr.sin_port);
std::cerr << " delay: " << pca.delay;
std::cerr << " period: " << pca.period;
std::cerr << " type: " << pca.type;
std::cerr << " source: " << source;
std::cerr << std::endl;
@ -1305,6 +1337,8 @@ void p3ConnectMgr::peerStatus(std::string id,
std::cerr << std::endl;
}
#endif
if (it->second.inConnAttempt)
{
std::cerr << "p3ConnectMgr::peerStatus() ALREADY IN CONNECT ATTEMPT: ";
@ -1314,22 +1348,34 @@ void p3ConnectMgr::peerStatus(std::string id,
return;
}
std::cerr << "p3ConnectMgr::peerStatus() Started CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
/* start a connection attempt */
it->second.actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
if (it->second.connAddrs.size() > 0)
{
std::cerr << "p3ConnectMgr::peerStatus() Started CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
it->second.actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
}
else
{
std::cerr << "p3ConnectMgr::peerStatus() No addr suitable for CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
}
}
void p3ConnectMgr::peerConnectRequest(std::string id, uint32_t type)
void p3ConnectMgr::peerConnectRequest(std::string id, struct sockaddr_in raddr,
uint32_t source)
{
std::cerr << "p3ConnectMgr::peerConnectRequest()";
std::cerr << " id: " << id;
std::cerr << " type: " << type;
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " source: " << source;
std::cerr << std::endl;
/* look up the id */
@ -1346,38 +1392,62 @@ void p3ConnectMgr::peerConnectRequest(std::string id, uint32_t type)
if (it == mOthersList.end())
{
/* not found - ignore */
std::cerr << "p3ConnectMgr::peerStatus() Peer Not Found - Ignore";
std::cerr << "p3ConnectMgr::peerConnectRequest() Peer Not Found - Ignore";
std::cerr << std::endl;
return;
}
std::cerr << "p3ConnectMgr::peerStatus() Peer is in mOthersList";
std::cerr << "p3ConnectMgr::peerConnectRequest() Peer is in mOthersList - Ignore";
std::cerr << std::endl;
return;
}
/* if already connected -> done */
if (it->second.state & RS_PEER_S_CONNECTED)
{
std::cerr << "p3ConnectMgr::peerConnectRequest() Already connected - Ignore";
std::cerr << std::endl;
return;
}
time_t now = time(NULL);
/* this is a UDP connection request (DHT only for the moment!) */
if (isValidNet(&(it->second.dht.raddr.sin_addr)))
if (isValidNet(&(raddr.sin_addr)))
{
/* add the remote address */
peerConnectAddress pca;
pca.ts = now;
pca.type = RS_NET_CONN_UDP_DHT_SYNC;
pca.addr = it->second.dht.raddr;
pca.delay = 0;
if (source == RS_CB_DHT)
{
pca.period = P3CONNMGR_UDP_DHT_DELAY;
std::cerr << "p3ConnectMgr::peerConnectRequest() source = DHT ";
std::cerr << std::endl;
}
else if (source == RS_CB_PROXY)
{
std::cerr << "p3ConnectMgr::peerConnectRequest() source = PROXY ";
std::cerr << std::endl;
pca.period = P3CONNMGR_UDP_PROXY_DELAY;
}
else
{
std::cerr << "p3ConnectMgr::peerConnectRequest() source = UNKNOWN ";
std::cerr << std::endl;
/* error! */
pca.period = P3CONNMGR_UDP_PROXY_DELAY;
}
std::cerr << "p3ConnectMgr::peerConnectRequest() period = " << pca.period;
std::cerr << std::endl;
pca.addr = raddr;
/* add to the start of list -> so handled next! */
//it->second.connAddrs.push_front(pca);
/* push to the back ... TCP ones should be tried first */
it->second.connAddrs.push_back(pca);
}
if (it->second.inConnAttempt)
{
/* -> it'll automatically use the addresses */
@ -1385,8 +1455,21 @@ void p3ConnectMgr::peerConnectRequest(std::string id, uint32_t type)
}
/* start a connection attempt */
it->second.actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
if (it->second.connAddrs.size() > 0)
{
std::cerr << "p3ConnectMgr::peerConnectRequest() Started CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
it->second.actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
}
else
{
std::cerr << "p3ConnectMgr::peerConnectRequest() No addr suitable for CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
}
}
@ -1683,6 +1766,8 @@ bool p3ConnectMgr::retryConnect(std::string id)
/* add in attempts ... local(TCP), remote(TCP)
*/
#ifndef P3CONNMGR_NO_TCP_CONNECTIONS
/* if address is same -> try local */
if ((isValidNet(&(it->second.localaddr.sin_addr))) &&
(sameNet(&(ownState.localaddr.sin_addr),
@ -1733,8 +1818,8 @@ bool p3ConnectMgr::retryConnect(std::string id)
}
/* otherwise try external ... (should check flags) */
if ((isValidNet(&(it->second.serveraddr.sin_addr))) && (1))
// (it->second.netMode & RS_NET_CONN_TCP_EXTERNAL))
if ((isValidNet(&(it->second.serveraddr.sin_addr))) &&
(it->second.netMode = RS_NET_MODE_EXT))
{
std::cerr << "p3ConnectMgr::retryConnect() Ext Address Valid (+EXT Flag): ";
std::cerr << inet_ntoa(it->second.serveraddr.sin_addr);
@ -1779,6 +1864,23 @@ bool p3ConnectMgr::retryConnect(std::string id)
std::cerr << std::endl;
}
}
#endif
if (it->second.netMode != RS_NET_MODE_EXT)
{
std::cerr << "p3ConnectMgr::retryConnect() trying UDP connection!";
std::cerr << " id: " << id;
std::cerr << std::endl;
/* attempt UDP connection */
mDhtMgr->notifyPeer(id);
}
else
{
std::cerr << "p3ConnectMgr::retryConnect() EXT so not trying UDP connection!";
std::cerr << " id: " << id;
std::cerr << std::endl;
}
if (it->second.inConnAttempt)
{
@ -1786,14 +1888,22 @@ bool p3ConnectMgr::retryConnect(std::string id)
return true;
}
/* start a connection attempt (only if we stuck something on the queue) */
/* start a connection attempt */
if (it->second.connAddrs.size() > 0)
{
std::cerr << "p3ConnectMgr::retryConnect() Started CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
it->second.actions |= RS_PEER_CONNECT_REQ;
mStatusChanged = true;
}
else
{
std::cerr << "p3ConnectMgr::retryConnect() No addr suitable for CONNECT ATTEMPT! ";
std::cerr << " id: " << id;
std::cerr << std::endl;
}
return true;
}

View File

@ -104,6 +104,8 @@ class peerConnectAddress
peerConnectAddress(); /* init */
struct sockaddr_in addr;
uint32_t delay; /* to stop simultaneous connects */
uint32_t period; /* UDP only */
uint32_t type;
time_t ts;
};
@ -200,11 +202,13 @@ void removeMonitor(pqiMonitor *mon);
virtual void peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t flags, uint32_t source);
virtual void peerConnectRequest(std::string id, uint32_t type);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
/****************** Connections *******************/
bool connectAttempt(std::string id, struct sockaddr_in &addr, uint32_t &type);
bool connectAttempt(std::string id, struct sockaddr_in &addr,
uint32_t &delay, uint32_t &period, uint32_t &type);
bool connectResult(std::string id, bool success, uint32_t flags);

View File

@ -743,7 +743,7 @@ int p3DhtMgr::checkNotifyDHT()
if (dhtNotify(peer.hash1, own.hash2, ""))
{
/* feedback to say we started it! */
connCb->peerConnectRequest(peer.id, RS_CONNECT_ACTIVE);
connCb->peerConnectRequest(peer.id, peer.raddr, RS_CB_DHT);
}
@ -1247,6 +1247,8 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
/* update data */
std::string peerid;
struct sockaddr_in raddr;
if (it != peers.end())
{
#ifdef DHT_DEBUG
@ -1267,6 +1269,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
doNotify = true;
it->second.notifyPending = 0;
peerid = (it->second).id;
raddr = (it->second).raddr;
}
}
else
@ -1281,7 +1284,7 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash)
/* do callback */
if (doNotify)
connCb->peerConnectRequest(peerid, RS_CONNECT_PASSIVE);
connCb->peerConnectRequest(peerid, raddr, RS_CB_DHT);
return true;
}
@ -1373,7 +1376,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash,
//ent.type, RS_CB_LOCAL_ADDR | RS_CB_REMOTE_ADDR, RS_CB_DHT);
if (doNotify)
{
connCb->peerConnectRequest(ent.id, RS_CONNECT_PASSIVE);
connCb->peerConnectRequest(ent.id, ent.raddr, RS_CB_DHT);
}
}

View File

@ -345,6 +345,9 @@ static const int NET_CONNECT_UNREACHABLE = 3;
static const int NET_CONNECT_FIREWALLED = 4;
static const int NET_CONNECT_FAILED = 5;
static const uint32_t NET_PARAM_CONNECT_DELAY = 1;
static const uint32_t NET_PARAM_CONNECT_PERIOD = 2;
class NetInterface
{
public:
@ -363,6 +366,8 @@ virtual int disconnect() = 0;
virtual int reset() = 0;
virtual std::string PeerId() { return peerId; }
virtual bool connect_parameter(uint32_t type, uint32_t value) { return false; }
protected:
PQInterface *parent() { return p; }

View File

@ -61,11 +61,14 @@ void pqiConnectCbDummy::peerStatus(std::string id,
std::cerr << std::endl;
}
void pqiConnectCbDummy::peerConnectRequest(std::string id, uint32_t type)
void pqiConnectCbDummy::peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source)
{
std::cerr << "pqiConnectCbDummy::peerConnectRequest()";
std::cerr << " id: " << id;
std::cerr << " type: " << type;
std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr);
std::cerr << ":" << ntohs(raddr.sin_port);
std::cerr << " source: " << source;
std::cerr << std::endl;
}

View File

@ -70,6 +70,7 @@ const uint32_t RS_STUN_FRIEND_OF_FRIEND = 0x0040;
#define RS_CB_DHT 1 /* from dht */
#define RS_CB_DISC 2 /* from peers */
#define RS_CB_PERSON 3 /* from connection */
#define RS_CB_PROXY 4 /* via proxy */
class pqipeer
@ -109,7 +110,8 @@ virtual void peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t flags, uint32_t source) = 0;
virtual void peerConnectRequest(std::string id, uint32_t type) = 0;
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source) = 0;
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags) = 0;
};
@ -125,7 +127,8 @@ virtual void peerStatus(std::string id,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t type, uint32_t mode, uint32_t source);
virtual void peerConnectRequest(std::string id, uint32_t type);
virtual void peerConnectRequest(std::string id,
struct sockaddr_in raddr, uint32_t source);
virtual void stunStatus(std::string id, struct sockaddr_in raddr, uint32_t type, uint32_t flags);
};

View File

@ -333,7 +333,7 @@ int pqiperson::stoplistening()
return 1;
}
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr)
int pqiperson::connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period)
{
{
std::ostringstream out;
@ -355,9 +355,14 @@ int pqiperson::connect(uint32_t type, struct sockaddr_in raddr)
out << "pqiperson::connect()";
out << " missing pqiconnect";
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
std::cerr << out.str();
//pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
return 0;
}
/* set the parameters */
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
(it->second)->connect(raddr);
// flag if we started a new connectionAttempt.

View File

@ -102,7 +102,7 @@ virtual ~pqiperson(); // must clean up children.
int reset();
int listen();
int stoplistening();
int connect(uint32_t type, struct sockaddr_in raddr);
int connect(uint32_t type, struct sockaddr_in raddr, uint32_t delay, uint32_t period);
// add in connection method.
int addChildInterface(uint32_t type, pqiconnect *pqi);

View File

@ -329,9 +329,11 @@ int pqipersongrp::connectPeer(std::string id)
return 0;
struct sockaddr_in addr;
uint32_t delay;
uint32_t period;
uint32_t type;
if (!mConnMgr->connectAttempt(id, addr, type))
if (!mConnMgr->connectAttempt(id, addr, delay, period, type))
{
std::cerr << " pqipersongrp::connectPeer() No Net Address";
std::cerr << std::endl;
@ -340,6 +342,8 @@ int pqipersongrp::connectPeer(std::string id)
std::cerr << " pqipersongrp::connectPeer() connectAttempt data id: " << id;
std::cerr << " addr: " << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port);
std::cerr << " delay: " << delay;
std::cerr << " period: " << period;
std::cerr << " type: " << type;
std::cerr << std::endl;
@ -360,7 +364,7 @@ int pqipersongrp::connectPeer(std::string id)
else
return 0;
p->connect(ptype, addr);
p->connect(ptype, addr, delay, period);
/* */
return 1;

View File

@ -95,6 +95,7 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3AuthMgr *am, p3ConnectM
attempt_ts(0),
net_attempt(0), net_failure(0), net_unreachable(0),
sameLAN(false), n_read_zero(0),
mConnectDelay(0), mConnectTS(0),
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
@ -246,6 +247,16 @@ int pqissl::reset()
return 1;
}
bool pqissl::connect_parameter(uint32_t type, uint32_t value)
{
if (type == NET_PARAM_CONNECT_DELAY)
{
mConnectDelay = value;
return true;
}
return NetInterface::connect_parameter(type, value);
}
/********** End of Implementation of NetInterface ******************/
/********** Implementation of BinInterface **************************
@ -333,11 +344,18 @@ int pqissl::ConnectAttempt()
{
case WAITING_NOT:
sslmode = PQISSL_ACTIVE; /* we're starting this one */
pqioutput(PQL_DEBUG_BASIC, pqisslzone,
"pqissl::ConnectAttempt() STATE = Not Waiting, starting connection");
case WAITING_DELAY:
pqioutput(PQL_DEBUG_BASIC, pqisslzone,
"pqissl::ConnectAttempt() STATE = Waiting Delay, starting connection");
sslmode = PQISSL_ACTIVE; /* we're starting this one */
return Initiate_Connection();
return Delay_Connection();
//return Initiate_Connection(); /* now called by Delay_Connection() */
break;
@ -424,6 +442,62 @@ int pqissl::Failed_Connection()
*
*/
int pqissl::Delay_Connection()
{
pqioutput(PQL_DEBUG_BASIC, pqisslzone,
"pqissl::Delay_Connection() Attempting Outgoing Connection....");
if (waiting == WAITING_NOT)
{
waiting = WAITING_DELAY;
/* set delay */
if (mConnectDelay == 0)
{
return Initiate_Connection();
}
/* set Connection TS.
*/
{
std::ostringstream out;
out << "pqissl::Delay_Connection() ";
out << " Delaying Connection to ";
out << PeerId() << " for ";
out << mConnectDelay;
out << " seconds";
pqioutput(PQL_DEBUG_BASIC, pqisslzone, out.str());
}
mConnectTS = time(NULL) + mConnectDelay;
return 0;
}
else if (waiting == WAITING_DELAY)
{
{
std::ostringstream out;
out << "pqissl::Delay_Connection() ";
out << " Connection to ";
out << PeerId() << " starting in ";
out << mConnectTS - time(NULL);
out << " seconds";
pqioutput(PQL_DEBUG_BASIC, pqisslzone, out.str());
}
if (time(NULL) > mConnectTS)
{
return Initiate_Connection();
}
return 0;
}
pqioutput(PQL_WARNING, pqisslzone,
"pqissl::Initiate_Connection() Already Attempt in Progress!");
return -1;
}
int pqissl::Initiate_Connection()
{
int err;
@ -432,7 +506,7 @@ int pqissl::Initiate_Connection()
pqioutput(PQL_DEBUG_BASIC, pqisslzone,
"pqissl::Initiate_Connection() Attempting Outgoing Connection....");
if (waiting != WAITING_NOT)
if (waiting != WAITING_DELAY)
{
pqioutput(PQL_WARNING, pqisslzone,
"pqissl::Initiate_Connection() Already Attempt in Progress!");

View File

@ -48,13 +48,12 @@
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#define WAITING_NOT 0
#define WAITING_SOCK_CONNECT 1
#define WAITING_SSL_CONNECTION 2
#define WAITING_SSL_AUTHORISE 3
#define WAITING_FAIL_INTERFACE 4
#define WAITING_DELAY 1
#define WAITING_SOCK_CONNECT 2
#define WAITING_SSL_CONNECTION 3
#define WAITING_SSL_AUTHORISE 4
#define WAITING_FAIL_INTERFACE 5
#define PQISSL_PASSIVE 0x00
#define PQISSL_ACTIVE 0x01
@ -105,6 +104,8 @@ virtual int stoplistening();
virtual int reset();
virtual int disconnect();
virtual bool connect_parameter(uint32_t type, uint32_t value);
// BinInterface
virtual int tick();
virtual int status();
@ -130,6 +131,9 @@ int waiting;
virtual int Failed_Connection();
// Start up connection with delay...
virtual int Delay_Connection();
// These two fns are overloaded for udp/etc connections.
virtual int Initiate_Connection();
virtual int Basic_Connection_Complete();
@ -190,8 +194,8 @@ virtual int net_internal_fcntl_nonblock(int fd) { return unix_fcntl_nonblock(fd)
int ssl_connect_timeout; /* timeout to ensure that we don't get stuck (can happen on udp!) */
private:
uint32_t mConnectDelay;
time_t mConnectTS;
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
@ -205,6 +209,7 @@ private:
p3ConnectMgr *mConnMgr;
private:
// ssl only fns.
int connectInterface(sockaddr_in&);

View File

@ -31,12 +31,16 @@
const int pqipersongrpzone = 354;
/****
* #define PQI_DISABLE_UDP 1
***/
/********************************** SSL Specific features ***************************/
#include "pqi/pqissl.h"
#include "pqi/pqissllistener.h"
#ifdef PQI_USE_PROXY
#ifndef PQI_DISABLE_UDP
#include "pqi/pqissludp.h"
#endif
@ -75,7 +79,7 @@ pqiperson * pqisslpersongrp::createPerson(std::string id, pqilistener *listener)
pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc);
#ifdef PQI_USE_PROXY
#ifndef PQI_DISABLE_UDP
pqissludp *pqius = new pqissludp(pqip, authMgr, mConnMgr);
RsSerialiser *rss2 = new RsSerialiser();

View File

@ -39,22 +39,25 @@
#include "pqi/pqidebug.h"
#include <sstream>
#include "util/rsnet.h"
const int pqissludpzone = 3144;
/* a final timeout, to ensure this never blocks completely
* 300 secs to complete udp/tcp/ssl connection.
* This is long as the udp connect can take some time.
*/
static const int PQI_SSLUDP_CONNECT_TIMEOUT = 300;
static const uint32_t PQI_SSLUDP_CONNECT_TIMEOUT = 600; /* 10 minutes - give it longer! */
static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */
/********** PQI SSL UDP STUFF **************************************/
pqissludp::pqissludp(PQInterface *parent, p3AuthMgr *am, p3ConnectMgr *cm)
:pqissl(NULL, parent, am, cm), tou_bio(NULL),
listen_checktime(0)
listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD)
{
attach();
sockaddr_clear(&remote_addr);
return;
}
@ -114,16 +117,27 @@ int pqissludp::attach()
// The Address determination is done centrally
int pqissludp::Initiate_Connection()
{
int err;
attach(); /* open socket */
remote_addr.sin_family = AF_INET;
pqioutput(PQL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Initiate_Connection() Attempting Outgoing Connection....");
if (waiting != WAITING_NOT)
/* decide if we're active or passive */
if (PeerId() < mConnMgr->getOwnId())
{
sslmode = PQISSL_ACTIVE;
}
else
{
sslmode = PQISSL_PASSIVE;
}
if (waiting != WAITING_DELAY)
{
pqioutput(PQL_WARNING, pqissludpzone,
"pqissludp::Initiate_Connection() Already Attempt in Progress!");
@ -138,6 +152,15 @@ int pqissludp::Initiate_Connection()
out << "pqissludp::Initiate_Connection() ";
out << "Connecting To: " << inet_ntoa(remote_addr.sin_addr) << ":";
out << ntohs(remote_addr.sin_port) << std::endl;
if (sslmode)
{
out << "Using ACTIVE Connect Mode (SSL_Connect)";
}
else
{
out << "Using PASSIVE Connect Mode (SSL_Accept)";
}
out << std::endl;
pqioutput(PQL_WARNING, pqissludpzone, out.str());
}
@ -166,7 +189,8 @@ int pqissludp::Initiate_Connection()
udp_connect_timeout = time(NULL) + PQI_SSLUDP_CONNECT_TIMEOUT;
/* <===================== UDP Difference *******************/
if (0 != (err = tou_connect(sockfd, (struct sockaddr *) &remote_addr, sizeof(remote_addr))))
if (0 != (err = tou_connect(sockfd, (struct sockaddr *) &remote_addr,
sizeof(remote_addr), mConnectPeriod)))
/* <===================== UDP Difference *******************/
{
int tou_err = tou_errno(sockfd);
@ -229,8 +253,11 @@ int pqissludp::Basic_Connection_Complete()
if (time(NULL) > udp_connect_timeout)
{
pqioutput(PQL_DEBUG_BASIC, pqissludpzone,
"pqissludp::Basic_Connection_Complete() Connectoin Timed Out!");
"pqissludp::Basic_Connection_Complete() Connection Timed Out!");
/* as sockfd is valid, this should close it all up */
std::cerr << "pqissludp::Basic_Connection_Complete() Connection Timed Out!";
std::cerr << std::endl;
reset();
}
@ -367,6 +394,15 @@ int pqissludp::stoplistening()
}
bool pqissludp::connect_parameter(uint32_t type, uint32_t value)
{
if (type == NET_PARAM_CONNECT_PERIOD)
{
mConnectPeriod = value;
return true;
}
return pqissl::connect_parameter(type, value);
}
/********** PQI STREAMER OVERLOADING *********************************/

View File

@ -66,6 +66,8 @@ virtual int stoplistening();
virtual int tick();
virtual int reset();
virtual bool connect_parameter(uint32_t type, uint32_t value);
// BinInterface.
// These are reimplemented.
virtual bool moretoread();
@ -96,6 +98,8 @@ private:
int udp_connect_timeout;
long listen_checktime;
uint32_t mConnectPeriod;
};
#endif // MRK_PQI_SSL_UDP_HEADER

View File

@ -232,7 +232,7 @@ int connect_socket_pair(int fd1, int fd2,
std::cerr << "Socket1 Connecting to: " << addr2 << std::endl;
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2));
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30);
if (err < 0)
{
err_num = tou_errno(fd1);

View File

@ -198,7 +198,7 @@ int main(int argc, char **argv)
#ifdef USE_TCP_SOCKET
err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
#else
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30);
#endif
if (err < 0)
{

View File

@ -236,7 +236,7 @@ int connect_socket_pair(int fd1, int fd2,
std::cerr << "Socket1 Connecting to: " << addr2 << std::endl;
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2));
err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30);
if (err < 0)
{
err_num = tou_errno(fd1);

View File

@ -60,7 +60,7 @@ class TcpPacket
/* other variables */
double ts; /* transmit time */
uint8 retrans; /* retransmit counter */
uint16 retrans; /* retransmit counter */
TcpPacket(uint8 *ptr, int size);
TcpPacket(); /* likely control packet */

View File

@ -56,9 +56,9 @@ int setupBinaryCheck(std::string fname);
static const uint32 kMaxQueueSize = 100;
static const uint32 kMaxPktRetransmit = 20;
static const uint32 kMaxSynPktRetransmit = 200; // max TTL of 40?
static const uint32 kMaxSynPktRetransmit = 1000; // up to 1000 (16 min?) startup
static const int TCP_STD_TTL = 64;
static const int TCP_STARTUP_COUNT_PER_TTL = 2;
static const int TCP_DEFAULT_FIREWALL_TTL = 4;
static const double RTT_ALPHA = 0.875;
@ -84,6 +84,9 @@ TcpStream::TcpStream(UdpSorter *lyr)
congestThreshold(TCP_MAX_WIN),
congestWinSize(MAX_SEG),
congestUpdate(0),
mTTL_period(0),
mTTL_start(0),
mTTL_end(0),
peerKnown(false),
udp(lyr)
{
@ -91,7 +94,7 @@ TcpStream::TcpStream(UdpSorter *lyr)
}
/* Stream Control! */
int TcpStream::connect(const struct sockaddr_in &raddr)
int TcpStream::connect(const struct sockaddr_in &raddr, uint32_t conn_period)
{
tcpMtx.lock(); /********** LOCK MUTEX *********/
@ -148,6 +151,10 @@ int TcpStream::connect(const struct sockaddr_in &raddr)
setTTL(1);
mTTL_start = getCurrentTS();
mTTL_period = conn_period;
mTTL_end = mTTL_start + mTTL_period;
toSend(pkt);
/* change state */
state = TCP_SYN_SENT;
@ -1864,25 +1871,39 @@ int TcpStream::retrans()
if ((pkt->hasSyn()) && (getTTL() < TCP_STD_TTL))
{
setTTL(1 + pkt->retrans /
TCP_STARTUP_COUNT_PER_TTL);
std::cerr << "TcpStream::retrans() Startup SYNs";
std::cerr << std::endl;
std::cerr << "TcpStream::retrans() retransTimeout: ";
std::cerr << retransTimeout << std::endl;
//setTTL(1 + pkt->retrans /
// TCP_STARTUP_COUNT_PER_TTL);
/* calculate a new TTL */
if (mTTL_end > cts)
{
setTTL(TCP_DEFAULT_FIREWALL_TTL);
}
else
{
setTTL(getTTL() + 1);
}
std::cerr << "TcpStream::retrans() retrans count: ";
std::cerr << pkt->retrans << std::endl;
std::cerr << "TcpStream::retrans() Setting TTL to: ";
std::cerr << (int) (1 + pkt->retrans /
TCP_STARTUP_COUNT_PER_TTL) << std::endl;
std::cerr << getTTL() << std::endl;
}
/* catch excessive retransmits
* (Allow Syn case more.... )
* - Allow Syn case more....
* - if not SYN or TTL has reached STD then timeout quickly.
*/
if ((pkt->hasSyn() && (pkt->retrans > kMaxSynPktRetransmit)) ||
(pkt->retrans > kMaxPktRetransmit))
(((!pkt->hasSyn()) || (TCP_STD_TTL == getTTL()))
&& (pkt->retrans > kMaxPktRetransmit)))
{
/* too many attempts close stream */
#ifdef DEBUG_TCP_STREAM

View File

@ -78,7 +78,7 @@ virtual ~TcpStream() { return; }
/* user interface */
int status(std::ostream &out);
int connect(const struct sockaddr_in &raddr);
int connect(const struct sockaddr_in &raddr, uint32_t conn_period);
int listenfor(const struct sockaddr_in &raddr);
bool isConnected();
@ -223,6 +223,10 @@ uint32 int_rbytes();
/* existing TTL for this stream (tweaked at startup) */
int ttl;
double mTTL_period;
double mTTL_start;
double mTTL_end;
struct sockaddr_in peeraddr;
bool peerKnown;

View File

@ -186,7 +186,7 @@ int main(int argc, char **argv)
#ifdef USE_TCP_SOCKET
err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
#else
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr));
err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30);
#endif
if (err < 0)
{

View File

@ -166,7 +166,7 @@ int tou_bind(int sockfd, const struct sockaddr *my_addr,
* - always non blocking.
*/
int tou_connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen)
socklen_t addrlen, uint32_t conn_period)
{
if (tou_streams[sockfd] == NULL)
{
@ -189,7 +189,7 @@ int tou_connect(int sockfd, const struct sockaddr *serv_addr,
*((const struct sockaddr_in *) serv_addr));
}
tous->tcp->connect(*(const struct sockaddr_in *) serv_addr);
tous->tcp->connect(*(const struct sockaddr_in *) serv_addr, conn_period);
tous->tcp->tick();
tou_tick_all();
if (tous->tcp->isConnected())
@ -377,12 +377,17 @@ int tou_close(int sockfd)
}
TcpOnUdp *tous = tou_streams[sockfd];
tous->tcp->tick();
tou_tick_all();
/* shut it down */
tous->tcp->close();
delete tous->tcp;
if (tous->tcp)
{
tous->tcp->tick();
/* shut it down */
tous->tcp->close();
delete tous->tcp;
}
delete tous;
tou_streams[sockfd] = NULL;
return 1;

View File

@ -78,6 +78,9 @@ int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char
* (2) connect: active: tou_connect() or passive: tou_listenfor().
* (3) use as a normal socket.
*
* connect() now has a conn_period parameter - this is the
* estimate (in seconds) of how slowly the connection should proceed.
*
* tou_bind() is not valid. tou_init performs this role.
* tou_listen() is not valid. (must listen for a specific address) use tou_listenfor() instead.
* tou_accept() can still be used.
@ -87,7 +90,8 @@ int tou_stunpeer(const struct sockaddr *ext_addr, socklen_t addrlen, const char
int tou_socket(int domain, int type, int protocol);
int tou_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); /* null op now */
int tou_listen(int sockfd, int backlog); /* null op now */
int tou_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
int tou_connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen, uint32_t conn_period);
int tou_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/* non-standard bonuses */

View File

@ -128,7 +128,7 @@ int main(int argc, char **argv)
if (toConnect)
{
tcp.connect(raddr);
tcp.connect(raddr, 30);
}
else
{