mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Added Second Queue, to check if connections are actually valid before installing.
* SSL_Peek is called on new connections, and we only accept it when there is data. * This should stop some of the unstable connections caused by wrong IP:Ports git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4533 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
23e49f7302
commit
b1ac8bc9d2
@ -83,7 +83,8 @@ int pqissllistenbase::tick()
|
|||||||
status();
|
status();
|
||||||
// check listen port.
|
// check listen port.
|
||||||
acceptconnection();
|
acceptconnection();
|
||||||
return continueaccepts();
|
continueaccepts();
|
||||||
|
return finaliseAccepts();
|
||||||
}
|
}
|
||||||
|
|
||||||
int pqissllistenbase::status()
|
int pqissllistenbase::status()
|
||||||
@ -440,22 +441,7 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool
|
|||||||
/* we have failed -> get certificate if possible */
|
/* we have failed -> get certificate if possible */
|
||||||
Extract_Failed_SSL_Certificate(ssl, &remote_addr);
|
Extract_Failed_SSL_Certificate(ssl, &remote_addr);
|
||||||
|
|
||||||
// other wise delete ssl connection.
|
closeConnection(fd, ssl);
|
||||||
// kill connection....
|
|
||||||
// so it will be removed from cache.
|
|
||||||
SSL_shutdown(ssl);
|
|
||||||
|
|
||||||
// close socket???
|
|
||||||
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
#ifndef WINDOWS_SYS // ie UNIX
|
|
||||||
shutdown(fd, SHUT_RDWR);
|
|
||||||
close(fd);
|
|
||||||
#else //WINDOWS_SYS
|
|
||||||
closesocket(fd);
|
|
||||||
#endif
|
|
||||||
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
// free connection.
|
|
||||||
SSL_free(ssl);
|
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "Read Error on the SSL Socket";
|
out << "Read Error on the SSL Socket";
|
||||||
@ -477,6 +463,22 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool
|
|||||||
pqioutput(PQL_WARNING, pqissllistenzone,
|
pqioutput(PQL_WARNING, pqissllistenzone,
|
||||||
"pqissllistenbase::completeConnection() Failed!");
|
"pqissllistenbase::completeConnection() Failed!");
|
||||||
|
|
||||||
|
closeConnection(fd, ssl);
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "Shutting it down!" << std::endl;
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
// failure -1, pending 0, sucess 1.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int pqissllistenbase::closeConnection(int fd, SSL *ssl)
|
||||||
|
{
|
||||||
|
/* else we shut it down! */
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, "pqissllistenbase::closeConnection() Shutting it Down!");
|
||||||
|
|
||||||
// delete ssl connection.
|
// delete ssl connection.
|
||||||
SSL_shutdown(ssl);
|
SSL_shutdown(ssl);
|
||||||
|
|
||||||
@ -491,16 +493,11 @@ int pqissllistenbase::continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool
|
|||||||
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
// free connection.
|
// free connection.
|
||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
|
|
||||||
std::ostringstream out;
|
|
||||||
out << "Shutting it down!" << std::endl;
|
|
||||||
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
|
||||||
|
|
||||||
// failure -1, pending 0, sucess 1.
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr)
|
int pqissllistenbase::Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr)
|
||||||
{
|
{
|
||||||
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
|
||||||
@ -563,6 +560,124 @@ int pqissllistenbase::continueaccepts()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ACCEPT_WAIT_TIME 30
|
||||||
|
|
||||||
|
int pqissllistenbase::finaliseAccepts()
|
||||||
|
{
|
||||||
|
|
||||||
|
// for each of the incoming sockets.... call continue.
|
||||||
|
std::list<AcceptedSSL>::iterator it;
|
||||||
|
|
||||||
|
time_t now = time(NULL);
|
||||||
|
for(it = accepted_ssl.begin(); it != accepted_ssl.end();)
|
||||||
|
{
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
|
||||||
|
"pqissllistenbase::finalisedAccepts() Continuing SSL Accept");
|
||||||
|
|
||||||
|
/* check that the socket is still active - how? */
|
||||||
|
int active = isSSLActive(it->mFd, it->mSSL);
|
||||||
|
if (active > 0)
|
||||||
|
{
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone,
|
||||||
|
"pqissllistenbase::finaliseAccepts() SSL Connection Ok => finaliseConnection");
|
||||||
|
|
||||||
|
if (0 > finaliseConnection(it->mFd, it->mSSL, it->mPeerId, it->mAddr))
|
||||||
|
{
|
||||||
|
closeConnection(it->mFd, it->mSSL);
|
||||||
|
}
|
||||||
|
it = accepted_ssl.erase(it);
|
||||||
|
}
|
||||||
|
else if (active < 0)
|
||||||
|
{
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone,
|
||||||
|
"pqissllistenbase::finaliseAccepts() SSL Connection Dead => closeConnection");
|
||||||
|
|
||||||
|
closeConnection(it->mFd, it->mSSL);
|
||||||
|
it = accepted_ssl.erase(it);
|
||||||
|
}
|
||||||
|
else if (now - it->mAcceptTS > ACCEPT_WAIT_TIME)
|
||||||
|
{
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone,
|
||||||
|
"pqissllistenbase::finaliseAccepts() SSL Connection Timed Out => closeConnection");
|
||||||
|
closeConnection(it->mFd, it->mSSL);
|
||||||
|
it = accepted_ssl.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone,
|
||||||
|
"pqissllistenbase::finaliseAccepts() SSL Connection Status Unknown");
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pqissllistenbase::isSSLActive(int fd, SSL *ssl)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* can we just get error? */
|
||||||
|
int bufsize = 8; /* just a little look */
|
||||||
|
uint8_t buf[bufsize];
|
||||||
|
int err = SSL_peek(ssl, buf, bufsize);
|
||||||
|
if (err <= 0)
|
||||||
|
{
|
||||||
|
int ssl_err = SSL_get_error(ssl, err);
|
||||||
|
int err_err = ERR_get_error();
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqissllistenbase::isSSLActive() ";
|
||||||
|
out << "Issues with SSL_Accept(" << err << ")!" << std::endl;
|
||||||
|
printSSLError(ssl, err, ssl_err, err_err, out);
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl_err == SSL_ERROR_ZERO_RETURN)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqissllistenbase::isSSLActive() SSL_ERROR_ZERO_RETURN ";
|
||||||
|
out << " Connection state unknown";
|
||||||
|
out << std::endl;
|
||||||
|
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
// zero means still continuing....
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((ssl_err == SSL_ERROR_WANT_READ) ||
|
||||||
|
(ssl_err == SSL_ERROR_WANT_WRITE))
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqissllistenbase::isSSLActive() SSL_ERROR_WANT_READ || SSL_ERROR_WANT_WRITE ";
|
||||||
|
out << " Connection state unknown";
|
||||||
|
out << std::endl;
|
||||||
|
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
// zero means still continuing....
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqissllistenbase::isSSLActive() ";
|
||||||
|
out << "Issues with SSL Peek(" << err << ") Likely the Connection was killed by Peer" << std::endl;
|
||||||
|
printSSLError(ssl, err, ssl_err, err_err, out);
|
||||||
|
pqioutput(PQL_ALERT, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "pqissllistenbase::isSSLActive() Successful Peer -> Connection Okay";
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************ PQI SSL LISTENER ****************************
|
/************************ PQI SSL LISTENER ****************************
|
||||||
*
|
*
|
||||||
@ -747,17 +862,65 @@ int pqissllistener::completeConnection(int fd, SSL *ssl, struct sockaddr_in &rem
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pqissl *pqis = it -> second;
|
// Cleanup cert.
|
||||||
|
X509_free(peercert);
|
||||||
|
|
||||||
// dont remove from the list of certificates.
|
// Pushback into Accepted List.
|
||||||
// want to allow a new connection to replace a faulty one!
|
AcceptedSSL as;
|
||||||
// listenaddr.erase(it);
|
as.mFd = fd;
|
||||||
|
as.mSSL = ssl;
|
||||||
|
as.mPeerId = newPeerId;
|
||||||
|
as.mAddr = remote_addr;
|
||||||
|
as.mAcceptTS = time(NULL);
|
||||||
|
|
||||||
// timestamp
|
accepted_ssl.push_back(as);
|
||||||
// done in sslroot... npc -> lr_timestamp = time(NULL);
|
|
||||||
|
std::ostringstream out;
|
||||||
|
|
||||||
|
out << "pqissllistener::completeConnection() Successful Connection with: " << newPeerId;
|
||||||
|
out << " for Connection:" << rs_inet_ntoa(remote_addr.sin_addr) << " Adding to WAIT-ACCEPT Queue";
|
||||||
|
out << std::endl;
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int pqissllistener::finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &remote_addr)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
std::map<std::string, pqissl *>::iterator it;
|
||||||
|
|
||||||
|
std::ostringstream out;
|
||||||
|
|
||||||
|
out << "pqissllistener::finaliseConnection()" << std::endl;
|
||||||
|
out << "checking: " << peerId << std::endl;
|
||||||
|
// check if cert is in the list.....
|
||||||
|
|
||||||
|
it = listenaddr.find(peerId);
|
||||||
|
if (it == listenaddr.end())
|
||||||
|
{
|
||||||
|
out << "No Matching Peer";
|
||||||
|
out << " for Connection:" << rs_inet_ntoa(remote_addr.sin_addr);
|
||||||
|
out << std::endl;
|
||||||
|
out << "pqissllistener => Shutting Down!" << std::endl;
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "Found Matching Peer";
|
||||||
|
out << " for Connection:" << rs_inet_ntoa(remote_addr.sin_addr);
|
||||||
|
out << std::endl;
|
||||||
|
out << "pqissllistener => Passing to pqissl module!" << std::endl;
|
||||||
|
pqioutput(PQL_WARNING, pqissllistenzone, out.str());
|
||||||
|
|
||||||
|
// hand off ssl conection.
|
||||||
|
pqissl *pqis = it -> second;
|
||||||
|
pqis -> accept(ssl, fd, remote_addr);
|
||||||
|
|
||||||
// hand off ssl conection.
|
|
||||||
pqis -> accept(ssl, fd, remote_addr);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,21 @@
|
|||||||
class pqissl;
|
class pqissl;
|
||||||
class p3PeerMgr;
|
class p3PeerMgr;
|
||||||
|
|
||||||
|
class AcceptedSSL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int mFd;
|
||||||
|
SSL *mSSL;
|
||||||
|
std::string mPeerId;
|
||||||
|
|
||||||
|
struct sockaddr_in mAddr;
|
||||||
|
time_t mAcceptTS;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class pqissllistenbase: public pqilistener
|
class pqissllistenbase: public pqilistener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -68,14 +83,18 @@ virtual int resetlisten();
|
|||||||
|
|
||||||
int acceptconnection();
|
int acceptconnection();
|
||||||
int continueaccepts();
|
int continueaccepts();
|
||||||
int continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool);
|
int finaliseAccepts();
|
||||||
|
|
||||||
|
int continueSSL(SSL *ssl, struct sockaddr_in remote_addr, bool);
|
||||||
|
int closeConnection(int fd, SSL *ssl);
|
||||||
|
int isSSLActive(int fd, SSL *ssl);
|
||||||
|
|
||||||
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr) = 0;
|
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr) = 0;
|
||||||
|
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr) = 0;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct sockaddr_in laddr;
|
struct sockaddr_in laddr;
|
||||||
|
std::list<AcceptedSSL> accepted_ssl;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -108,6 +127,7 @@ int removeListenPort(std::string id);
|
|||||||
virtual int status();
|
virtual int status();
|
||||||
|
|
||||||
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr);
|
virtual int completeConnection(int sockfd, SSL *in_connection, struct sockaddr_in &raddr);
|
||||||
|
virtual int finaliseConnection(int fd, SSL *ssl, std::string peerId, struct sockaddr_in &raddr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user