mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-05 21:29:23 -04:00
Fixed the ssl connexion problem. However, for connexions to occur correctly, both peers should upgrade to this new version
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1062 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
56b3370cd1
commit
1424d85384
3 changed files with 285 additions and 96 deletions
|
@ -1343,12 +1343,8 @@ int pqissl::accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr) // initiat
|
||||||
int pqissl::senddata(void *data, int len)
|
int pqissl::senddata(void *data, int len)
|
||||||
{
|
{
|
||||||
int tmppktlen ;
|
int tmppktlen ;
|
||||||
int nbtries = 0 ;
|
|
||||||
#ifdef WIN32
|
tmppktlen = SSL_write(ssl_connection, data, len) ;
|
||||||
while( (tmppktlen = SSL_write(ssl_connection, data, len)) == -1 && nbtries++ < 50) Sleep(300);
|
|
||||||
#else
|
|
||||||
while( (tmppktlen = SSL_write(ssl_connection, data, len)) == -1 && nbtries++ < 50) usleep(300000);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (len != tmppktlen)
|
if (len != tmppktlen)
|
||||||
{
|
{
|
||||||
|
@ -1377,7 +1373,7 @@ int pqissl::senddata(void *data, int len)
|
||||||
out << "SSL_write() SSL_ERROR_WANT_WRITE";
|
out << "SSL_write() SSL_ERROR_WANT_WRITE";
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
rslog(RSL_ALERT, pqisslzone, out.str());
|
rslog(RSL_ALERT, pqisslzone, out.str());
|
||||||
std::cerr << out.str() ;
|
// std::cerr << out.str() ;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (err == SSL_ERROR_WANT_READ)
|
else if (err == SSL_ERROR_WANT_READ)
|
||||||
|
@ -1415,21 +1411,9 @@ int pqissl::readdata(void *data, int len)
|
||||||
// multiple slices.
|
// multiple slices.
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
static const int max_tries = 50 ;
|
|
||||||
int nbtries = 0 ;
|
|
||||||
int tmppktlen ;
|
int tmppktlen ;
|
||||||
|
|
||||||
// This is a loop to prevent loosing a connexion just because there is a
|
tmppktlen = SSL_read(ssl_connection, (void*)((unsigned long int)data+(unsigned long int)total_len), len-total_len) ;
|
||||||
// lag in the network. This happens quite often actually. The total time
|
|
||||||
// to wait if nothing happens is 50*20ms = 1 sec, which is not so much.
|
|
||||||
// This current version seems to work fine.
|
|
||||||
//
|
|
||||||
while( -1 == (tmppktlen = SSL_read(ssl_connection, (void*)((unsigned long int)data+(unsigned long int)total_len), len-total_len)) && nbtries++ < max_tries)
|
|
||||||
#ifdef WIN32
|
|
||||||
Sleep(20) ;
|
|
||||||
#else
|
|
||||||
usleep(20000) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Need to catch errors.....
|
// Need to catch errors.....
|
||||||
//
|
//
|
||||||
|
@ -1472,8 +1456,8 @@ int pqissl::readdata(void *data, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
rslog(RSL_ALERT, pqisslzone, out.str());
|
rslog(RSL_ALERT, pqisslzone, out.str());
|
||||||
std::cerr << out.str() << std::endl ;
|
// std::cerr << out.str() << std::endl ;
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the only real error we expect */
|
/* the only real error we expect */
|
||||||
|
@ -1496,12 +1480,11 @@ int pqissl::readdata(void *data, int len)
|
||||||
std::cerr << out.str() << std::endl ;
|
std::cerr << out.str() << std::endl ;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (error == SSL_ERROR_WANT_READ)
|
else if (error == SSL_ERROR_WANT_READ) // SSL_WANT_READ is not a crittical error. It's just a sign that
|
||||||
{
|
{ // the internal SSL buffer is not ready to accept more data. So -1
|
||||||
out << "SSL_read() SSL_ERROR_WANT_READ";
|
out << "SSL_read() SSL_ERROR_WANT_READ"; // is returned, and the connexion will be retried as is on next
|
||||||
out << std::endl;
|
out << std::endl; // call of readdata().
|
||||||
rslog(RSL_ALERT, pqisslzone, out.str());
|
rslog(RSL_ALERT, pqisslzone, out.str());
|
||||||
std::cerr << out.str() << std::endl ;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -58,6 +58,7 @@ pqistreamer::pqistreamer(RsSerialiser *rss, std::string id, BinInterface *bio_in
|
||||||
/* allocated once */
|
/* allocated once */
|
||||||
pkt_rpend_size = getRsPktMaxSize();
|
pkt_rpend_size = getRsPktMaxSize();
|
||||||
pkt_rpending = malloc(pkt_rpend_size);
|
pkt_rpending = malloc(pkt_rpend_size);
|
||||||
|
reading_state = reading_state_initial ;
|
||||||
|
|
||||||
// avoid uninitialized (and random) memory read.
|
// avoid uninitialized (and random) memory read.
|
||||||
memset(pkt_rpending,0,pkt_rpend_size) ;
|
memset(pkt_rpending,0,pkt_rpend_size) ;
|
||||||
|
@ -68,20 +69,20 @@ pqistreamer::pqistreamer(RsSerialiser *rss, std::string id, BinInterface *bio_in
|
||||||
setRate(true, 0);
|
setRate(true, 0);
|
||||||
setRate(false, 0);
|
setRate(false, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::pqistreamer()";
|
out << "pqistreamer::pqistreamer()";
|
||||||
out << " Initialisation!" << std::endl;
|
out << " Initialisation!" << std::endl;
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bio_in)
|
if (!bio_in)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::pqistreamer()";
|
out << "pqistreamer::pqistreamer()";
|
||||||
out << " NULL bio, FATAL ERROR!" << std::endl;
|
out << " NULL bio, FATAL ERROR!" << std::endl;
|
||||||
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -89,28 +90,28 @@ pqistreamer::pqistreamer(RsSerialiser *rss, std::string id, BinInterface *bio_in
|
||||||
|
|
||||||
pqistreamer::~pqistreamer()
|
pqistreamer::~pqistreamer()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::~pqistreamer()";
|
out << "pqistreamer::~pqistreamer()";
|
||||||
out << " Destruction!" << std::endl;
|
out << " Destruction!" << std::endl;
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bio_flags & BIN_FLAGS_NO_CLOSE)
|
if (bio_flags & BIN_FLAGS_NO_CLOSE)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::~pqistreamer()";
|
out << "pqistreamer::~pqistreamer()";
|
||||||
out << " Not Closing BinInterface!" << std::endl;
|
out << " Not Closing BinInterface!" << std::endl;
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
else if (bio)
|
else if (bio)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::~pqistreamer()";
|
out << "pqistreamer::~pqistreamer()";
|
||||||
out << " Deleting BinInterface!" << std::endl;
|
out << " Deleting BinInterface!" << std::endl;
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
|
|
||||||
delete bio;
|
delete bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up serialiser */
|
/* clean up serialiser */
|
||||||
|
@ -354,17 +355,17 @@ int pqistreamer::handleincomingitem(RsItem *pqi)
|
||||||
|
|
||||||
int pqistreamer::handleoutgoing()
|
int pqistreamer::handleoutgoing()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::handleoutgoing()";
|
out << "pqistreamer::handleoutgoing()";
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxbytes = outAllowedBytes();
|
int maxbytes = outAllowedBytes();
|
||||||
int sentbytes = 0;
|
int sentbytes = 0;
|
||||||
int len;
|
int len;
|
||||||
int ss;
|
int ss;
|
||||||
// std::cerr << "pqistreamer: maxbytes=" << maxbytes<< std::endl ;
|
// std::cerr << "pqistreamer: maxbytes=" << maxbytes<< std::endl ;
|
||||||
|
|
||||||
std::list<void *>::iterator it;
|
std::list<void *>::iterator it;
|
||||||
|
|
||||||
|
@ -379,8 +380,8 @@ int pqistreamer::handleoutgoing()
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::handleoutgoing() Not active -> Clearing Pkt!";
|
out << "pqistreamer::handleoutgoing() Not active -> Clearing Pkt!";
|
||||||
// std::cerr << out.str() ;
|
// std::cerr << out.str() ;
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
for(it = out_data.begin(); it != out_data.end(); )
|
for(it = out_data.begin(); it != out_data.end(); )
|
||||||
{
|
{
|
||||||
|
@ -389,8 +390,8 @@ int pqistreamer::handleoutgoing()
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::handleoutgoing() Not active -> Clearing DPkt!";
|
out << "pqistreamer::handleoutgoing() Not active -> Clearing DPkt!";
|
||||||
// std::cerr << out.str() ;
|
// std::cerr << out.str() ;
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* also remove the pending packets */
|
/* also remove the pending packets */
|
||||||
|
@ -403,7 +404,7 @@ int pqistreamer::handleoutgoing()
|
||||||
outSentBytes(sentbytes);
|
outSentBytes(sentbytes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a very simple round robin
|
// a very simple round robin
|
||||||
|
|
||||||
bool sent = true;
|
bool sent = true;
|
||||||
|
@ -446,17 +447,17 @@ int pqistreamer::handleoutgoing()
|
||||||
out << "Problems with Send Data! (only " << ss << " bytes sent" << ", total pkt size=" << len ;
|
out << "Problems with Send Data! (only " << ss << " bytes sent" << ", total pkt size=" << len ;
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
std::cerr << out.str() ;
|
std::cerr << out.str() ;
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
|
|
||||||
outSentBytes(sentbytes);
|
outSentBytes(sentbytes);
|
||||||
// pkt_wpending will keep til next time.
|
// pkt_wpending will kept til next time.
|
||||||
// ensuring exactly the same data is written (openSSL requirement).
|
// ensuring exactly the same data is written (openSSL requirement).
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " Success!" << ", sent " << len << " bytes" << std::endl;
|
out << " Success!" << ", sent " << len << " bytes" << std::endl;
|
||||||
// std::cerr << out.str() ;
|
// std::cerr << out.str() ;
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
|
|
||||||
free(pkt_wpending);
|
free(pkt_wpending);
|
||||||
pkt_wpending = NULL;
|
pkt_wpending = NULL;
|
||||||
|
@ -472,15 +473,15 @@ int pqistreamer::handleoutgoing()
|
||||||
|
|
||||||
/* Handles reading from input stream.
|
/* Handles reading from input stream.
|
||||||
*/
|
*/
|
||||||
|
#ifdef OLD_VERSION
|
||||||
int pqistreamer::handleincoming()
|
int pqistreamer::handleincoming()
|
||||||
{
|
{
|
||||||
int readbytes = 0;
|
int readbytes = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::handleincoming()";
|
out << "pqistreamer::handleincoming()";
|
||||||
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(bio->isactive()))
|
if (!(bio->isactive()))
|
||||||
|
@ -505,8 +506,8 @@ int pqistreamer::handleincoming()
|
||||||
// read the basic block (minimum packet size)
|
// read the basic block (minimum packet size)
|
||||||
if (blen != (tmplen = bio->readdata(block, blen)))
|
if (blen != (tmplen = bio->readdata(block, blen)))
|
||||||
{
|
{
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
||||||
"pqistreamer::handleincoming() Didn't read BasePkt!");
|
"pqistreamer::handleincoming() Didn't read BasePkt!");
|
||||||
|
|
||||||
// error.... (either blocked or failure)
|
// error.... (either blocked or failure)
|
||||||
inReadBytes(readbytes);
|
inReadBytes(readbytes);
|
||||||
|
@ -514,8 +515,8 @@ int pqistreamer::handleincoming()
|
||||||
{
|
{
|
||||||
|
|
||||||
// most likely blocked!
|
// most likely blocked!
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
||||||
"pqistreamer::handleincoming() read blocked");
|
"pqistreamer::handleincoming() read blocked");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -523,8 +524,8 @@ int pqistreamer::handleincoming()
|
||||||
{
|
{
|
||||||
// assume the worse, that
|
// assume the worse, that
|
||||||
// the stream is bust ... and jump away.
|
// the stream is bust ... and jump away.
|
||||||
pqioutput(PQL_WARNING, pqistreamerzone,
|
pqioutput(PQL_WARNING, pqistreamerzone,
|
||||||
"pqistreamer::handleincoming() Error in bio read");
|
"pqistreamer::handleincoming() Error in bio read");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else // tmplen > 0
|
else // tmplen > 0
|
||||||
|
@ -533,7 +534,7 @@ int pqistreamer::handleincoming()
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "pqistreamer::handleincoming() Incomplete ";
|
out << "pqistreamer::handleincoming() Incomplete ";
|
||||||
out << "(Strange) read of " << tmplen << " bytes";
|
out << "(Strange) read of " << tmplen << " bytes";
|
||||||
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,15 +545,15 @@ int pqistreamer::handleincoming()
|
||||||
int extralen = getRsItemSize(block) - blen;
|
int extralen = getRsItemSize(block) - blen;
|
||||||
if (extralen > maxlen - blen)
|
if (extralen > maxlen - blen)
|
||||||
{
|
{
|
||||||
pqioutput(PQL_ALERT, pqistreamerzone, "ERROR: Read Packet too Big!");
|
pqioutput(PQL_ALERT, pqistreamerzone, "ERROR: Read Packet too Big!");
|
||||||
|
|
||||||
pqiNotify *notify = getPqiNotify();
|
pqiNotify *notify = getPqiNotify();
|
||||||
if (notify)
|
if (notify)
|
||||||
{
|
{
|
||||||
std::string title =
|
std::string title =
|
||||||
"Warning: Bad Packet Read";
|
"Warning: Bad Packet Read";
|
||||||
|
|
||||||
std::ostringstream msgout;
|
std::ostringstream msgout;
|
||||||
msgout << " **** WARNING **** \n";
|
msgout << " **** WARNING **** \n";
|
||||||
msgout << "Retroshare has caught a BAD Packet Read";
|
msgout << "Retroshare has caught a BAD Packet Read";
|
||||||
msgout << "\n";
|
msgout << "\n";
|
||||||
|
@ -589,15 +590,15 @@ int pqistreamer::handleincoming()
|
||||||
out << "Error Completing Read (read ";
|
out << "Error Completing Read (read ";
|
||||||
out << tmplen << "/" << extralen << ")" << std::endl;
|
out << tmplen << "/" << extralen << ")" << std::endl;
|
||||||
std::cerr << out.str() ;
|
std::cerr << out.str() ;
|
||||||
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
||||||
|
|
||||||
pqiNotify *notify = getPqiNotify();
|
pqiNotify *notify = getPqiNotify();
|
||||||
if (notify)
|
if (notify)
|
||||||
{
|
{
|
||||||
std::string title =
|
std::string title =
|
||||||
"Warning: Error Completing Read";
|
"Warning: Error Completing Read";
|
||||||
|
|
||||||
std::ostringstream msgout;
|
std::ostringstream msgout;
|
||||||
msgout << " **** WARNING **** \n";
|
msgout << " **** WARNING **** \n";
|
||||||
msgout << "Retroshare has experienced an unexpected Read ERROR";
|
msgout << "Retroshare has experienced an unexpected Read ERROR";
|
||||||
msgout << "\n";
|
msgout << "\n";
|
||||||
|
@ -609,7 +610,12 @@ int pqistreamer::handleincoming()
|
||||||
|
|
||||||
std::string msg = msgout.str();
|
std::string msg = msgout.str();
|
||||||
std::cout << msg << std::endl ;
|
std::cout << msg << std::endl ;
|
||||||
// notify->AddSysMessage(0, RS_SYS_WARNING, title, msg);
|
std::cout << "block = "
|
||||||
|
<< (int)(((unsigned char*)block)[0]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[1]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[2]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[3]) << std::endl ;
|
||||||
|
// notify->AddSysMessage(0, RS_SYS_WARNING, title, msg);
|
||||||
}
|
}
|
||||||
bio->close();
|
bio->close();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -630,35 +636,229 @@ int pqistreamer::handleincoming()
|
||||||
|
|
||||||
// create packet, based on header.
|
// create packet, based on header.
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Read Data Block -> Incoming Pkt(";
|
out << "Read Data Block -> Incoming Pkt(";
|
||||||
out << blen + extralen << ")" << std::endl;
|
out << blen + extralen << ")" << std::endl;
|
||||||
// std::cerr << out.str() ;
|
// std::cerr << out.str() ;
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cerr << "Deserializing packet of size " << pktlen <<std::endl ;
|
// std::cerr << "Deserializing packet of size " << pktlen <<std::endl ;
|
||||||
RsItem *pkt = rsSerialiser->deserialise(block, &pktlen);
|
RsItem *pkt = rsSerialiser->deserialise(block, &pktlen);
|
||||||
|
|
||||||
if ((pkt != NULL) && (0 < handleincomingitem(pkt)))
|
if ((pkt != NULL) && (0 < handleincomingitem(pkt)))
|
||||||
{
|
{
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone,
|
||||||
"Successfully Read a Packet!");
|
"Successfully Read a Packet!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pqioutput(PQL_ALERT, pqistreamerzone,
|
pqioutput(PQL_ALERT, pqistreamerzone,
|
||||||
"Failed to handle Packet!");
|
"Failed to handle Packet!");
|
||||||
inReadBytes(readbytes);
|
inReadBytes(readbytes);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cerr << "pqistreamer:: total bytes read = " << readbytes << std::endl ;
|
// std::cerr << "pqistreamer:: total bytes read = " << readbytes << std::endl ;
|
||||||
inReadBytes(readbytes);
|
inReadBytes(readbytes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int pqistreamer::handleincoming()
|
||||||
|
{
|
||||||
|
int readbytes = 0;
|
||||||
|
static const int max_failed_read_attempts = 60 ;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqistreamer::handleincoming()";
|
||||||
|
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(bio->isactive()))
|
||||||
|
{
|
||||||
|
reading_state = reading_state_initial ;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enough space to read any packet.
|
||||||
|
int maxlen = pkt_rpend_size;
|
||||||
|
void *block = pkt_rpending;
|
||||||
|
|
||||||
|
// initial read size: basic packet.
|
||||||
|
int blen = getRsPktBaseSize();
|
||||||
|
|
||||||
|
int maxin = inAllowedBytes();
|
||||||
|
|
||||||
|
switch(reading_state)
|
||||||
|
{
|
||||||
|
case reading_state_initial: goto start_packet_read ;
|
||||||
|
case reading_state_packet_started: goto continue_packet ;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_packet_read:
|
||||||
|
{ // scope to ensure variable visibility
|
||||||
|
// read the basic block (minimum packet size)
|
||||||
|
int tmplen;
|
||||||
|
|
||||||
|
if (blen != (tmplen = bio->readdata(block, blen)))
|
||||||
|
{
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() Didn't read BasePkt!");
|
||||||
|
|
||||||
|
// error.... (either blocked or failure)
|
||||||
|
if (tmplen == 0)
|
||||||
|
{
|
||||||
|
// most likely blocked!
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() read blocked");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (tmplen < 0)
|
||||||
|
{
|
||||||
|
// Most likely it is that the packet is pending but could not be read by pqissl because of stream flow.
|
||||||
|
// So we return without an error, and leave the machine state in 'start_read'.
|
||||||
|
//
|
||||||
|
pqioutput(PQL_WARNING, pqistreamerzone, "pqistreamer::handleincoming() Error in bio read");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else // tmplen > 0
|
||||||
|
{
|
||||||
|
// strange case....This should never happen as partial reads are handled by pqissl below.
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqistreamer::handleincoming() Incomplete ";
|
||||||
|
out << "(Strange) read of " << tmplen << " bytes";
|
||||||
|
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readbytes += blen;
|
||||||
|
reading_state = reading_state_packet_started ;
|
||||||
|
}
|
||||||
|
continue_packet:
|
||||||
|
{
|
||||||
|
// workout how much more to read.
|
||||||
|
int extralen = getRsItemSize(block) - blen;
|
||||||
|
|
||||||
|
if (extralen > maxlen - blen)
|
||||||
|
{
|
||||||
|
pqioutput(PQL_ALERT, pqistreamerzone, "ERROR: Read Packet too Big!");
|
||||||
|
|
||||||
|
pqiNotify *notify = getPqiNotify();
|
||||||
|
if (notify)
|
||||||
|
{
|
||||||
|
std::string title =
|
||||||
|
"Warning: Bad Packet Read";
|
||||||
|
|
||||||
|
std::ostringstream msgout;
|
||||||
|
msgout << " **** WARNING **** \n";
|
||||||
|
msgout << "Retroshare has caught a BAD Packet Read";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "This is normally caused by connecting to an";
|
||||||
|
msgout << " OLD version of Retroshare";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "(M:" << maxlen << " B:" << blen << " E:" << extralen << ")\n";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "Please get your friends to upgrade to the latest version";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "If you are sure the error was not caused by an old version";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "Please report the problem to Retroshare's developers";
|
||||||
|
msgout << "\n";
|
||||||
|
|
||||||
|
std::string msg = msgout.str();
|
||||||
|
notify->AddSysMessage(0, RS_SYS_WARNING, title, msg);
|
||||||
|
}
|
||||||
|
bio->close();
|
||||||
|
reading_state = reading_state_initial ; // restart at state 1.
|
||||||
|
failed_read_attempts = 0 ;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Used to exit now! exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extralen > 0)
|
||||||
|
{
|
||||||
|
void *extradata = (void *) (((char *) block) + blen);
|
||||||
|
int tmplen ;
|
||||||
|
|
||||||
|
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
|
||||||
|
if(++failed_read_attempts > max_failed_read_attempts)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "Error Completing Read (read ";
|
||||||
|
out << tmplen << "/" << extralen << ")" << std::endl;
|
||||||
|
std::cerr << out.str() ;
|
||||||
|
pqioutput(PQL_ALERT, pqistreamerzone, out.str());
|
||||||
|
|
||||||
|
pqiNotify *notify = getPqiNotify();
|
||||||
|
if (notify)
|
||||||
|
{
|
||||||
|
std::string title = "Warning: Error Completing Read";
|
||||||
|
|
||||||
|
std::ostringstream msgout;
|
||||||
|
msgout << " **** WARNING **** \n";
|
||||||
|
msgout << "Retroshare has experienced an unexpected Read ERROR";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "(M:" << maxlen << " B:" << blen;
|
||||||
|
msgout << " E:" << extralen << " R:" << tmplen << ")\n";
|
||||||
|
msgout << "\n";
|
||||||
|
msgout << "Please contact the developers.";
|
||||||
|
msgout << "\n";
|
||||||
|
|
||||||
|
std::string msg = msgout.str();
|
||||||
|
std::cout << msg << std::endl ;
|
||||||
|
std::cout << "block = "
|
||||||
|
<< (int)(((unsigned char*)block)[0]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[1]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[2]) << " "
|
||||||
|
<< (int)(((unsigned char*)block)[3]) << std::endl ;
|
||||||
|
// notify->AddSysMessage(0, RS_SYS_WARNING, title, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bio->close();
|
||||||
|
reading_state = reading_state_initial ; // restart at state 1.
|
||||||
|
failed_read_attempts = 0 ;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0 ; // this is just a SSL_WANT_READ error. Don't panic, we'll re-try the read soon.
|
||||||
|
// we assume readdata() returned either -1 or the complete read size.
|
||||||
|
|
||||||
|
readbytes += extralen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create packet, based on header.
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "Read Data Block -> Incoming Pkt(";
|
||||||
|
out << blen + extralen << ")" << std::endl;
|
||||||
|
// std::cerr << out.str() ;
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::cerr << "Deserializing packet of size " << pktlen <<std::endl ;
|
||||||
|
|
||||||
|
uint32_t pktlen = blen+extralen ;
|
||||||
|
RsItem *pkt = rsSerialiser->deserialise(block, &pktlen);
|
||||||
|
inReadBytes(readbytes);
|
||||||
|
|
||||||
|
if ((pkt != NULL) && (0 < handleincomingitem(pkt)))
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!");
|
||||||
|
else
|
||||||
|
pqioutput(PQL_ALERT, pqistreamerzone, "Failed to handle Packet!");
|
||||||
|
|
||||||
|
reading_state = reading_state_initial ; // restart at state 1.
|
||||||
|
}
|
||||||
|
|
||||||
|
if(maxin > readbytes && bio->moretoread())
|
||||||
|
goto start_packet_read ;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* BandWidth Management Assistance */
|
/* BandWidth Management Assistance */
|
||||||
|
|
|
@ -82,6 +82,12 @@ void inReadBytes(int );
|
||||||
int pkt_rpend_size; // size of pkt_rpending.
|
int pkt_rpend_size; // size of pkt_rpending.
|
||||||
void *pkt_rpending; // storage for read in pending packets.
|
void *pkt_rpending; // storage for read in pending packets.
|
||||||
|
|
||||||
|
enum {reading_state_packet_started=1,
|
||||||
|
reading_state_initial=0 } ;
|
||||||
|
|
||||||
|
int reading_state ;
|
||||||
|
int failed_read_attempts ;
|
||||||
|
|
||||||
// Temp Storage for transient data.....
|
// Temp Storage for transient data.....
|
||||||
std::list<void *> out_pkt; // Cntrl / Search / Results queue
|
std::list<void *> out_pkt; // Cntrl / Search / Results queue
|
||||||
std::list<void *> out_data; // FileData - secondary queue.
|
std::list<void *> out_data; // FileData - secondary queue.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue