print "<br>Type answers for a few puzzles and submit<br>";\r
\r
\r
- $st=$db->prepare("SELECT UUID,Day FROM tblIntroductionPuzzleRequests WHERE UUID NOT IN (SELECT UUID FROM tblIdentityIntroductionInserts) AND Day>='".gmdate('Y-m-d',strtotime('-1 day'))."' AND Found='true';");\r
+ $st=$db->prepare("SELECT UUID,Day FROM tblIntroductionPuzzleRequests WHERE UUID NOT IN (SELECT UUID FROM tblIdentityIntroductionInserts) AND Day>='".gmdate('Y-m-d',strtotime('-1 day'))."' AND Found='true';");\r
$st->execute();\r
\r
while($record=$st->fetch())\r
--- /dev/null
+<?php\r
+\r
+ include_once('config.php');\r
+ include_once('linkbar.php');\r
+ \r
+function content()\r
+{\r
+ global $dblocation;\r
+ \r
+ $db=new PDO('sqlite:'.$dblocation);\r
+ $st=$db->prepare("SELECT tblLocalIdentity.Name, COUNT(Inserted) FROM tblLocalIdentity LEFT JOIN tblIdentityIntroductionInserts ON tblLocalIdentity.LocalIdentityID=tblIdentityIntroductionInserts.LocalIdentityID WHERE (Inserted='true' OR Inserted IS NULL) GROUP BY tblLocalIdentity.LocalIdentityID;");\r
+ $st->execute();\r
+ \r
+ ?>\r
+ <h2>Introduction Status</h2>\r
+ <table>\r
+ <tr>\r
+ <th>Identity</th>\r
+ <th>Successful introduction inserts</th>\r
+ </tr>\r
+ <?php\r
+ while($record=$st->fetch())\r
+ {\r
+ ?>\r
+ <tr>\r
+ <td>\r
+ <?php print $record[0]; ?>\r
+ </td>\r
+ <td>\r
+ <?php print $record[1]; ?>\r
+ </td>\r
+ </tr>\r
+ <?php \r
+ }\r
+ ?>\r
+ </table>\r
+ <?php\r
+}\r
+ \r
+ include_once('template.php');\r
+\r
+?>
\ No newline at end of file
<li><a href="options.php">Options</a></li>\r
<li><a href="createidentity.php">Create Identity</a></li>\r
<li><a href="introduce.php">Introduce Identity</a></li>\r
+ <li><a href="introductionstatus.php">Introduction Status</a></li>\r
<li><a href="addpeeridentity.php">Manually Add Peer</a></li>\r
</ul>\r
</div>\r
--- /dev/null
+#ifndef _trustlistinserter_\r
+#define _trustlistinserter_\r
+\r
+#include "../idatabase.h"\r
+#include "../ilogger.h"\r
+#include "../datetime.h"\r
+#include "ifreenetregistrable.h"\r
+#include "ifcpconnected.h"\r
+#include "ifcpmessagehandler.h"\r
+#include "iperiodicprocessor.h"\r
+\r
+class TrustListInserter:public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
+{\r
+public:\r
+ TrustListInserter();\r
+ TrustListInserter(FCPv2 *fcp);\r
+\r
+ void FCPConnected();\r
+ void FCPDisconnected();\r
+\r
+ const bool HandleMessage(FCPMessage &message);\r
+\r
+ void Process();\r
+\r
+ void RegisterWithThread(FreenetMasterThread *thread);\r
+\r
+private:\r
+ void Initialize();\r
+ void CheckForNeededInsert();\r
+ void StartInsert(const long localidentityid, const std::string &privatekey);\r
+\r
+ std::string m_messagebase;\r
+ DateTime m_lastchecked;\r
+ \r
+};\r
+\r
+#endif // _trustlistinserter_\r
--- /dev/null
+#ifndef _trustlistrequester_\r
+#define _trustlistrequester_\r
+\r
+#include "../idatabase.h"\r
+#include "../ilogger.h"\r
+#include "../datetime.h"\r
+#include "ifreenetregistrable.h"\r
+#include "ifcpconnected.h"\r
+#include "ifcpmessagehandler.h"\r
+#include "iperiodicprocessor.h"\r
+\r
+class TrustListRequester:public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
+{\r
+public:\r
+ TrustListRequester();\r
+ TrustListRequester(FCPv2 *fcp);\r
+\r
+ void FCPDisconnected();\r
+ void FCPConnected();\r
+\r
+ const bool HandleMessage(FCPMessage &message);\r
+\r
+ void Process();\r
+\r
+ void RegisterWithThread(FreenetMasterThread *thread);\r
+\r
+private:\r
+ void Initialize();\r
+ void PopulateIDList(); // clear and re-populate m_ids with identities we want to query\r
+ void StartRequest(const long identityid);\r
+ const bool HandleAllData(FCPMessage &message);\r
+ const bool HandleGetFailed(FCPMessage &message);\r
+ void RemoveFromRequestList(const long identityid);\r
+\r
+ DateTime m_tempdate;\r
+ std::string m_messagebase;\r
+ long m_maxrequests;\r
+ std::vector<long> m_requesting; // list of ids we are currently requesting from\r
+ std::map<long,bool> m_ids; // map of all ids we know and whether we have requested file from them yet\r
+ \r
+};\r
+\r
+#endif // _trustlistrequester_\r
--- /dev/null
+#ifndef _trustlistxml_\r
+#define _trustlistxml_\r
+\r
+#include "../ifmsxmldocument.h"\r
+#include "../ilogger.h"\r
+\r
+#include <vector>\r
+\r
+class TrustListXML:public IFMSXMLDocument,public ILogger\r
+{\r
+public:\r
+ TrustListXML();\r
+\r
+ std::string GetXML();\r
+ \r
+ const bool ParseXML(const std::string &xml);\r
+\r
+ void ClearTrust() { m_trust.clear(); }\r
+\r
+ void AddTrust(const std::string &identity, const long messagetrust, const long trustlisttrust);\r
+\r
+ const long TrustCount() { return m_trust.size(); }\r
+ std::string GetIdentity(const long index);\r
+ long GetMessageTrust(const long index);\r
+ long GetTrustListTrust(const long index);\r
+\r
+private:\r
+ struct trust\r
+ {\r
+ trust(const std::string &identity, const long messagetrust, const long trustlisttrust):m_identity(identity),m_messagetrust(messagetrust),m_trustlisttrust(trustlisttrust) {}\r
+ std::string m_identity;\r
+ long m_messagetrust;\r
+ long m_trustlisttrust;\r
+ };\r
+\r
+ void Initialize();\r
+\r
+ std::vector<trust> m_trust;\r
+ \r
+};\r
+\r
+#endif // _trustlistxml_\r
#include <vector>\r
#include <zthread/Thread.h>\r
\r
-#define FMS_VERSION "0.0.1"\r
+#define FMS_VERSION "0.0.2"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
\r
std::string DateTime::Format(const std::string &formatstring) const\r
{\r
- std::string returnval="";\r
- char *str=new char[512];\r
- memset(str,0,512);\r
+ std::vector<char> str(256,0);\r
\r
- strftime(str,511,formatstring.c_str(),&m_tm);\r
+ size_t len=strftime(&str[0],str.size()-1,formatstring.c_str(),&m_tm);\r
\r
- if(str)\r
- {\r
- returnval=str;\r
- delete [] str;\r
- }\r
-\r
- return returnval;\r
+ return std::string(str.begin(),str.begin()+len);\r
}\r
\r
void DateTime::Normalize()\r
#include "../../include/freenet/freenetmasterthread.h"\r
#include "../../include/option.h"\r
+#include "../../include/uuidgenerator.h"\r
#include "../../include/stringfunctions.h"\r
#include "../../include/freenet/unkeyedidcreator.h"\r
#include "../../include/freenet/identityinserter.h"\r
#include "../../include/freenet/introductionpuzzlerequester.h"\r
#include "../../include/freenet/introductionpuzzleremover.h"\r
#include "../../include/freenet/identityintroductioninserter.h"\r
+#include "../../include/freenet/trustlistinserter.h"\r
\r
#include <zthread/Thread.h>\r
\r
\r
if(m_fcp.Connect(m_fcphost.c_str(),m_fcpport)==true)\r
{\r
+ UUIDGenerator uuid;\r
+ std::string clientname="FMSClient-"+uuid.Generate();\r
// send ClientHello message to node\r
- m_fcp.SendMessage("ClientHello",2,"Name","FMSClient","ExpectedVersion","2.0");\r
+ m_fcp.SendMessage("ClientHello",2,"Name",clientname.c_str(),"ExpectedVersion","2.0");\r
\r
m_log->WriteLog(LogFile::LOGLEVEL_INFO,__FUNCTION__" connected to node");\r
\r
m_registrables.push_back(new IntroductionPuzzleRequester(&m_fcp));\r
m_registrables.push_back(new IntroductionPuzzleRemover());\r
m_registrables.push_back(new IdentityIntroductionInserter(&m_fcp));\r
+ m_registrables.push_back(new TrustListInserter(&m_fcp));\r
\r
for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
{\r
Initialize();\r
}\r
\r
-void IdentityInserter::FCPConnected()\r
-{\r
- m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false';");\r
-}\r
-\r
void IdentityInserter::CheckForNeededInsert()\r
{\r
+ DateTime now;\r
DateTime date;\r
+ now.SetToGMTime();\r
date.SetToGMTime();\r
// set date to 1 hour back\r
date.Add(0,0,-1);\r
\r
+ // Because of importance of Identity.xml, if we are now at the next day we immediately want to insert identities so change the date back to now\r
+ if(date.GetDay()!=now.GetDay())\r
+ {\r
+ date=now;\r
+ }\r
+\r
SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID FROM tblLocalIdentity WHERE PrivateKey IS NOT NULL AND PrivateKey <> '' AND InsertingIdentity='false' AND (LastInsertedIdentity<'"+date.Format("%Y-%m-%d %H:%M:%S")+"' OR LastInsertedIdentity IS NULL) ORDER BY LastInsertedIdentity;");\r
\r
if(rs.Empty()==false)\r
\r
}\r
\r
+void IdentityInserter::FCPConnected()\r
+{\r
+ m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false';");\r
+}\r
+\r
+\r
void IdentityInserter::FCPDisconnected()\r
{\r
\r
StringFunctions::Convert(localidentityid,idstring);\r
date.SetToGMTime();\r
\r
- SQLite3DB::Recordset rs=m_db->Query("SELECT Name,PrivateKey,SingleUse FROM tblLocalIdentity WHERE LocalIdentityID="+idstring+";");\r
+ SQLite3DB::Recordset rs=m_db->Query("SELECT Name,PrivateKey,SingleUse,PublishTrustList,PublishBoardList FROM tblLocalIdentity WHERE LocalIdentityID="+idstring+";");\r
\r
if(rs.Empty()==false)\r
{\r
long index=0;\r
std::string indexstr;\r
std::string singleuse="false";\r
+ std::string publishtrustlist="false";\r
+ std::string publishboardlist="false";\r
\r
now.SetToGMTime();\r
\r
}\r
singleuse=="true" ? idxml.SetSingleUse(true) : idxml.SetSingleUse(false);\r
\r
+ if(rs.GetField(3))\r
+ {\r
+ publishtrustlist=rs.GetField(3);\r
+ }\r
+ publishtrustlist=="true" ? idxml.SetPublishTrustList(true) : idxml.SetPublishTrustList(false);\r
+\r
+ if(rs.GetField(4))\r
+ {\r
+ publishboardlist=rs.GetField(3);\r
+ }\r
+ publishboardlist=="true" ? idxml.SetPublishBoardList(true) : idxml.SetPublishBoardList(false);\r
+\r
data=idxml.GetXML();\r
StringFunctions::Convert(data.size(),datasizestr);\r
\r
if(xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
{\r
\r
- st=m_db->Prepare("UPDATE tblIdentity SET Name=?, SingleUse=?, LastSeen=? WHERE IdentityID=?");\r
+ st=m_db->Prepare("UPDATE tblIdentity SET Name=?, SingleUse=?, LastSeen=?, PublishTrustList=?, PublishBoardList=? WHERE IdentityID=?");\r
st.Bind(0,xml.GetName());\r
if(xml.GetSingleUse()==true)\r
{\r
st.Bind(1,"false");\r
}\r
st.Bind(2,now.Format("%Y-%m-%d %H:%M:%S"));\r
- st.Bind(3,identityid);\r
+ if(xml.GetPublishTrustList()==true)\r
+ {\r
+ st.Bind(3,"true");\r
+ }\r
+ else\r
+ {\r
+ st.Bind(3,"false");\r
+ }\r
+ if(xml.GetPublishBoardList()==true)\r
+ {\r
+ st.Bind(4,"true");\r
+ }\r
+ else\r
+ {\r
+ st.Bind(4,"false");\r
+ }\r
+ st.Bind(5,identityid);\r
st.Step();\r
st.Finalize();\r
\r
st.Step();\r
st.Finalize();\r
\r
+ // if fatal error or collision - mark index\r
+ if(message["Fatal"]=="true" || message["Code"]=="9")\r
+ {\r
+ m_db->Execute("UPDATE tblIntroductionPuzzleInserts SET Day='"+idparts[5]+"', InsertIndex="+idparts[2]+", FoundSolution='true' WHERE UUID='"+idparts[3]+"';");\r
+ }\r
+\r
m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,__FUNCTION__" failed to insert puzzle "+idparts[3]);\r
\r
return true;\r
--- /dev/null
+#include "../../include/freenet/trustlistinserter.h"\r
+#include "../../include/option.h"\r
+#include "../../include/freenet/trustlistxml.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+TrustListInserter::TrustListInserter()\r
+{\r
+ Initialize();\r
+}\r
+\r
+TrustListInserter::TrustListInserter(FCPv2 *fcp):IFCPConnected(fcp)\r
+{\r
+ Initialize();\r
+}\r
+\r
+void TrustListInserter::CheckForNeededInsert()\r
+{\r
+ DateTime date;\r
+ date.SetToGMTime();\r
+ date.Add(0,0,-1);\r
+ SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID, PrivateKey FROM tblLocalIdentity WHERE PrivateKey IS NOT NULL AND PrivateKey <> '' AND PublishTrustList='true' AND InsertingTrustList='false' AND (LastInsertedTrustList<='"+date.Format("%Y-%m-%d %H:%M:%S")+"' OR LastInsertedTrustList IS NULL);");\r
+\r
+ if(rs.Empty()==false)\r
+ {\r
+ StartInsert(rs.GetInt(0),rs.GetField(1));\r
+ }\r
+}\r
+\r
+void TrustListInserter::FCPConnected()\r
+{\r
+ m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false';");\r
+}\r
+\r
+void TrustListInserter::FCPDisconnected()\r
+{\r
+\r
+}\r
+\r
+const bool TrustListInserter::HandleMessage(FCPMessage &message)\r
+{\r
+\r
+ if(message["Identifier"].find("TrustListInserter")==0)\r
+ {\r
+ \r
+ DateTime now;\r
+ std::vector<std::string> idparts;\r
+\r
+ now.SetToGMTime();\r
+ StringFunctions::Split(message["Identifier"],"|",idparts);\r
+\r
+ // no action for URIGenerated\r
+ if(message.GetName()=="URIGenerated")\r
+ {\r
+ return true;\r
+ }\r
+\r
+ // no action for IdentifierCollision\r
+ if(message.GetName()=="IdentifierCollision")\r
+ {\r
+ return true;\r
+ }\r
+\r
+ if(message.GetName()=="PutSuccessful")\r
+ {\r
+ m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false', LastInsertedTrustList='"+now.Format("%Y-%m-%d %H:%M:%S")+"' WHERE LocalIdentityID="+idparts[1]+";");\r
+ m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,__FUNCTION__" inserted TrustList xml");\r
+ return true;\r
+ }\r
+\r
+ if(message.GetName()=="PutFailed")\r
+ {\r
+ m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false' WHERE LocalIdentityID="+idparts[1]+";");\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,__FUNCTION__" failure inserting TrustList xml. Code="+message["Code"]+" Description="+message["CodeDescription"]);\r
+ \r
+ // if code 9 (collision), then insert index into inserted table\r
+ if(message["Code"]=="9")\r
+ {\r
+ m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
+ }\r
+ \r
+ return true;\r
+ }\r
+\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void TrustListInserter::Initialize()\r
+{\r
+ Option::instance()->Get("MessageBase",m_messagebase);\r
+ m_lastchecked.SetToGMTime();\r
+}\r
+\r
+void TrustListInserter::Process()\r
+{\r
+ DateTime now;\r
+ now.SetToGMTime();\r
+\r
+ // check every minute\r
+ if(m_lastchecked<=(now-(1.0/1440.0)))\r
+ {\r
+ CheckForNeededInsert();\r
+ m_lastchecked=now;\r
+ }\r
+}\r
+\r
+void TrustListInserter::RegisterWithThread(FreenetMasterThread *thread)\r
+{\r
+ thread->RegisterFCPConnected(this);\r
+ thread->RegisterFCPMessageHandler(this);\r
+ thread->RegisterPeriodicProcessor(this);\r
+}\r
+\r
+void TrustListInserter::StartInsert(const long localidentityid, const std::string &privatekey)\r
+{\r
+ FCPMessage message;\r
+ TrustListXML xml;\r
+ std::string data;\r
+ std::string datasizestr;\r
+ std::string publickey;\r
+ int messagetrust;\r
+ int trustlisttrust;\r
+ DateTime now;\r
+ int index;\r
+ std::string indexstr;\r
+ std::string localidentityidstr;\r
+\r
+ now.SetToGMTime();\r
+ \r
+ // build the xml file\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey, LocalMessageTrust, LocalTrustListTrust FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey<>'';");\r
+ st.Step();\r
+ while(st.RowReturned())\r
+ {\r
+ st.ResultText(0,publickey);\r
+ st.ResultInt(1,messagetrust);\r
+ st.ResultInt(2,trustlisttrust);\r
+ xml.AddTrust(publickey,messagetrust,trustlisttrust);\r
+ st.Step();\r
+ }\r
+\r
+ // get next insert index\r
+ st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblTrustListInserts WHERE LocalIdentityID=? AND Day=?;");\r
+ st.Bind(0,localidentityid);\r
+ st.Bind(1,now.Format("%Y-%m-%d"));\r
+ st.Step();\r
+\r
+ index=0;\r
+ if(st.RowReturned() && st.ResultNull(0)==false)\r
+ {\r
+ st.ResultInt(0,index);\r
+ index++;\r
+ }\r
+\r
+ StringFunctions::Convert(localidentityid,localidentityidstr);\r
+ StringFunctions::Convert(index,indexstr);\r
+\r
+ data=xml.GetXML();\r
+ StringFunctions::Convert(data.size(),datasizestr);\r
+\r
+ message.SetName("ClientPut");\r
+ message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|TrustList|"+indexstr+".xml";\r
+ message["Identifier"]="TrustListInserter|"+localidentityidstr+"|"+indexstr+"|"+message["URI"];\r
+ message["UploadFrom"]="direct";\r
+ message["DataLength"]=datasizestr;\r
+ m_fcp->SendMessage(message);\r
+ m_fcp->SendRaw(data.c_str(),data.size());\r
+\r
+ m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='true' WHERE LocalIdentityID="+localidentityidstr+";");\r
+\r
+}
\ No newline at end of file
--- /dev/null
+#include "../../include/freenet/trustlistrequester.h"\r
+#include "../../include/option.h"\r
+#include "../../include/stringfunctions.h"\r
+#include "../../include/freenet/trustlistxml.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+TrustListRequester::TrustListRequester()\r
+{\r
+ Initialize();\r
+}\r
+\r
+TrustListRequester::TrustListRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
+{\r
+ Initialize();\r
+}\r
+\r
+void TrustListRequester::FCPConnected()\r
+{\r
+ m_requesting.clear();\r
+ PopulateIDList();\r
+}\r
+\r
+void TrustListRequester::FCPDisconnected()\r
+{\r
+ \r
+}\r
+\r
+const bool TrustListRequester::HandleAllData(FCPMessage &message)\r
+{\r
+ DateTime now;\r
+ SQLite3DB::Statement st;\r
+ std::vector<std::string> idparts;\r
+ long datalength;\r
+ std::vector<char> data;\r
+ TrustListXML xml;\r
+ long identityid;\r
+ long index;\r
+\r
+ now.SetToGMTime();\r
+ StringFunctions::Split(message["Identifier"],"|",idparts);\r
+ StringFunctions::Convert(message["DataLength"],datalength);\r
+ StringFunctions::Convert(idparts[1],identityid);\r
+ StringFunctions::Convert(idparts[2],index);\r
+\r
+ // wait for all data to be received from connection\r
+ while(m_fcp->Connected() && m_fcp->ReceiveBufferSize()<datalength)\r
+ {\r
+ m_fcp->Update(1);\r
+ }\r
+\r
+ // if we got disconnected- return immediately\r
+ if(m_fcp->Connected()==false)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // receive the file\r
+ data.resize(datalength);\r
+ m_fcp->ReceiveRaw(&data[0],datalength);\r
+\r
+ // parse file into xml and update the database\r
+ if(xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
+ {\r
+ st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey=?;");\r
+ // loop through all trust entries in xml and add to database if we don't already know them\r
+ for(long i=0; i<xml.TrustCount(); i++)\r
+ {\r
+ std::string identity;\r
+ identity=xml.GetIdentity(i);\r
+\r
+ //TODO get the trust levels as well\r
+\r
+ st.Bind(0,identity);\r
+ st.Step();\r
+ if(st.RowReturned()==false)\r
+ {\r
+ m_db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('"+identity+"','"+now.Format("%Y-%m-%d %H:%M:%S")+"');");\r
+ }\r
+ st.Reset();\r
+ }\r
+\r
+ st=m_db->Prepare("INSERT INTO tblTrustListRequests(IdentityID,Day,RequestIndex,Found) VALUES(?,?,?,'true');");\r
+ st.Bind(0,identityid);\r
+ st.Bind(1,idparts[4]);\r
+ st.Bind(2,index);\r
+ st.Step();\r
+ st.Finalize();\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,__FUNCTION__" parsed Identity XML file : "+message["Identifier"]);\r
+ }\r
+ else\r
+ {\r
+ // bad data - mark index\r
+ st=m_db->Prepare("INSERT INTO tblTrustListRequests(IdentityID,Day,RequestIndex,Found) VALUES(?,?,?,'false');");\r
+ st.Bind(0,identityid);\r
+ st.Bind(1,idparts[4]);\r
+ st.Bind(2,index);\r
+ st.Step();\r
+ st.Finalize();\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,__FUNCTION__" error parsing TrustList XML file : "+message["Identifier"]);\r
+ }\r
+\r
+ // remove this identityid from request list\r
+ RemoveFromRequestList(identityid);\r
+\r
+ return true;\r
+\r
+}\r
+\r
+const bool TrustListRequester::HandleGetFailed(FCPMessage &message)\r
+{\r
+ DateTime now;\r
+ SQLite3DB::Statement st;\r
+ std::vector<std::string> idparts;\r
+ long identityid;\r
+ long index;\r
+\r
+ now.SetToGMTime();\r
+ StringFunctions::Split(message["Identifier"],"|",idparts);\r
+ StringFunctions::Convert(idparts[1],identityid);\r
+ StringFunctions::Convert(idparts[2],index); \r
+\r
+ // if this is a fatal error - insert index into database so we won't try to download this index again\r
+ if(message["Fatal"]=="true")\r
+ {\r
+ st=m_db->Prepare("INSERT INTO tblTrustListRequests(IdentityID,Day,RequestIndex,Found) VALUES(?,?,?,'false');");\r
+ st.Bind(0,identityid);\r
+ st.Bind(1,idparts[4]);\r
+ st.Bind(2,index);\r
+ st.Step();\r
+ st.Finalize();\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,__FUNCTION__" fatal error requesting "+message["Identifier"]);\r
+ }\r
+\r
+ // remove this identityid from request list\r
+ RemoveFromRequestList(identityid);\r
+\r
+ return true;\r
+\r
+}\r
+\r
+const bool TrustListRequester::HandleMessage(FCPMessage &message)\r
+{\r
+\r
+ if(message["Identifier"].find("TrustListRequester")==0)\r
+ {\r
+ if(message.GetName()=="DataFound")\r
+ {\r
+ return true;\r
+ }\r
+\r
+ if(message.GetName()=="AllData")\r
+ {\r
+ return HandleAllData(message);\r
+ }\r
+\r
+ if(message.GetName()=="GetFailed")\r
+ {\r
+ return HandleGetFailed(message);\r
+ }\r
+\r
+ if(message.GetName()=="IdentifierCollision")\r
+ {\r
+ // remove one of the ids from the requesting list\r
+ long identityid=0;\r
+ std::vector<std::string> idparts;\r
+ StringFunctions::Split(message["Identifier"],"|",idparts);\r
+ StringFunctions::Convert(idparts[1],identityid);\r
+ RemoveFromRequestList(identityid);\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void TrustListRequester::Initialize()\r
+{\r
+ std::string tempval="";\r
+ Option::instance()->Get("MaxIdentityRequests",tempval);\r
+ StringFunctions::Convert(tempval,m_maxrequests);\r
+ if(m_maxrequests<1)\r
+ {\r
+ m_maxrequests=1;\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"Option MaxTrustListRequests is currently set at "+tempval+". It must be 1 or greater.");\r
+ }\r
+ if(m_maxrequests>100)\r
+ {\r
+ m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxTrustListRequests is currently set at "+tempval+". This value might be incorrectly configured.");\r
+ }\r
+ Option::instance()->Get("MessageBase",m_messagebase);\r
+ m_tempdate.SetToGMTime();\r
+}\r
+\r
+void TrustListRequester::PopulateIDList()\r
+{\r
+ DateTime date;\r
+ int id;\r
+\r
+ date.SetToGMTime();\r
+\r
+ // select identities we want to query (we've seen them today and they are publishing trust list) - sort by their trust level (descending) with secondary sort on how long ago we saw them (ascending)\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+date.Format("%Y-%m-%d")+"' AND PublishTrustList='true' AND LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;");\r
+ st.Step();\r
+\r
+ m_ids.clear();\r
+\r
+ while(st.RowReturned())\r
+ {\r
+ st.ResultInt(0,id);\r
+ m_ids[id]=false;\r
+ st.Step();\r
+ }\r
+}\r
+\r
+void TrustListRequester::Process()\r
+{\r
+ // max is the smaller of the config value or the total number of identities we will request from\r
+ long max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
+\r
+ // try to keep up to max requests going\r
+ if(m_requesting.size()<max)\r
+ {\r
+ std::map<long,bool>::iterator i=m_ids.begin();\r
+ while(i!=m_ids.end() && (*i).second==true)\r
+ {\r
+ i++;\r
+ }\r
+\r
+ if(i!=m_ids.end())\r
+ {\r
+ StartRequest((*i).first);\r
+ }\r
+ else\r
+ {\r
+ // we requested from all ids in the list, repopulate the list\r
+ PopulateIDList();\r
+ }\r
+ }\r
+ // special case - if there were 0 identities on the list when we started then we will never get a chance to repopulate the list\r
+ // this will recheck for ids every minute\r
+ DateTime now;\r
+ now.SetToGMTime();\r
+ if(m_tempdate<(now-(1.0/1440.0)))\r
+ {\r
+ PopulateIDList();\r
+ m_tempdate=now;\r
+ }\r
+\r
+}\r
+\r
+void TrustListRequester::RegisterWithThread(FreenetMasterThread *thread)\r
+{\r
+ thread->RegisterFCPConnected(this);\r
+ thread->RegisterFCPMessageHandler(this);\r
+ thread->RegisterPeriodicProcessor(this);\r
+}\r
+\r
+void TrustListRequester::RemoveFromRequestList(const long identityid)\r
+{\r
+ std::vector<long>::iterator i=m_requesting.begin();\r
+ while(i!=m_requesting.end() && (*i)!=identityid)\r
+ {\r
+ i++;\r
+ }\r
+ if(i!=m_requesting.end())\r
+ {\r
+ m_requesting.erase(i);\r
+ }\r
+}\r
+\r
+void TrustListRequester::StartRequest(const long identityid)\r
+{\r
+ DateTime now;\r
+ FCPMessage message;\r
+ std::string publickey;\r
+ int index;\r
+ std::string indexstr;\r
+ std::string identityidstr;\r
+\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey FROM tblIdentity WHERE IdentityID=?;");\r
+ st.Bind(0,identityid);\r
+ st.Step();\r
+\r
+ if(st.RowReturned())\r
+ {\r
+ st.ResultText(0,publickey);\r
+\r
+ now.SetToGMTime();\r
+\r
+ SQLite3DB::Statement st2=m_db->Prepare("SELECT MAX(RequestIndex) FROM tblTrustListRequests WHERE Day=? AND IdentityID=?;");\r
+ st2.Bind(0,now.Format("%Y-%m-%d"));\r
+ st2.Bind(1,identityid);\r
+ st2.Step();\r
+\r
+ index=0;\r
+ if(st2.RowReturned())\r
+ {\r
+ if(st2.ResultNull(0)==false)\r
+ {\r
+ st2.ResultInt(0,index);\r
+ index++;\r
+ }\r
+ }\r
+ st2.Finalize();\r
+\r
+ StringFunctions::Convert(index,indexstr);\r
+ StringFunctions::Convert(identityid,identityidstr);\r
+\r
+ message.SetName("ClientGet");\r
+ message["URI"]=publickey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|TrustList|"+indexstr+".xml";\r
+ message["Identifier"]="TrustListRequester|"+identityidstr+"|"+indexstr+"|"+message["URI"];\r
+ message["ReturnType"]="direct";\r
+ message["MaxSize"]="1000000"; // 1 MB\r
+\r
+ m_fcp->SendMessage(message);\r
+\r
+ m_requesting.push_back(identityid);\r
+ }\r
+ st.Finalize();\r
+\r
+ m_ids[identityid]=true;\r
+\r
+}\r
--- /dev/null
+#include "../../include/freenet/trustlistxml.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+TrustListXML::TrustListXML()\r
+{\r
+ Initialize();\r
+}\r
+\r
+void TrustListXML::AddTrust(const std::string &identity, const long messagetrust, const long trustlisttrust)\r
+{\r
+ m_trust.push_back(trust(identity,messagetrust,trustlisttrust));\r
+}\r
+\r
+std::string TrustListXML::GetIdentity(const long index)\r
+{\r
+ if(index>=0 && index<m_trust.size())\r
+ {\r
+ return m_trust[index].m_identity;\r
+ }\r
+ else\r
+ {\r
+ return "";\r
+ }\r
+}\r
+\r
+long TrustListXML::GetMessageTrust(const long index)\r
+{\r
+ if(index>=0 && index<m_trust.size())\r
+ {\r
+ return m_trust[index].m_messagetrust;\r
+ }\r
+ else\r
+ {\r
+ return -1;\r
+ } \r
+}\r
+\r
+long TrustListXML::GetTrustListTrust(const long index)\r
+{\r
+ if(index>=0 && index<m_trust.size())\r
+ {\r
+ return m_trust[index].m_trustlisttrust;\r
+ }\r
+ else\r
+ {\r
+ return -1;\r
+ }\r
+}\r
+\r
+std::string TrustListXML::GetXML()\r
+{\r
+ TiXmlDocument td;\r
+ TiXmlDeclaration *tdec=new TiXmlDeclaration("1.0","UTF-8","");\r
+ TiXmlElement *tid;\r
+ TiXmlPrinter tp;\r
+\r
+ td.LinkEndChild(tdec);\r
+ tid=new TiXmlElement("TrustList");\r
+ td.LinkEndChild(tid);\r
+\r
+ for(std::vector<trust>::iterator i=m_trust.begin(); i!=m_trust.end(); i++)\r
+ {\r
+ std::string messagetrust;\r
+ std::string trustlisttrust;\r
+ StringFunctions::Convert((*i).m_messagetrust,messagetrust);\r
+ StringFunctions::Convert((*i).m_trustlisttrust,trustlisttrust);\r
+ TiXmlElement *tr=new TiXmlElement("Trust");\r
+ tid->LinkEndChild(tr);\r
+ tr->LinkEndChild(XMLCreateCDATAElement("Identity",(*i).m_identity));\r
+ tr->LinkEndChild(XMLCreateTextElement("MessageTrustLevel",messagetrust));\r
+ tr->LinkEndChild(XMLCreateTextElement("TrustListTrustLevel",trustlisttrust));\r
+ }\r
+\r
+ td.Accept(&tp);\r
+ return std::string(tp.CStr());\r
+}\r
+\r
+void TrustListXML::Initialize()\r
+{\r
+ m_trust.clear();\r
+}\r
+\r
+const bool TrustListXML::ParseXML(const std::string &xml)\r
+{\r
+ TiXmlDocument td;\r
+ td.Parse(xml.c_str());\r
+\r
+ if(!td.Error())\r
+ {\r
+ std::string identity;\r
+ std::string messagetruststr;\r
+ std::string trustlisttruststr;\r
+ long messagetrust;\r
+ long trustlisttrust;\r
+ TiXmlText *txt;\r
+ TiXmlHandle hnd(&td);\r
+ TiXmlNode *node;\r
+\r
+ Initialize();\r
+\r
+ node=hnd.FirstChild("TrustList").FirstChild("Trust").ToElement();\r
+ while(node)\r
+ {\r
+ identity="";\r
+ messagetrust=-1;\r
+ trustlisttrust=-1;\r
+\r
+ TiXmlHandle hnd2(node);\r
+ txt=hnd2.FirstChild("Identity").FirstChild().ToText();\r
+ if(txt)\r
+ {\r
+ identity=txt->ValueStr();\r
+ }\r
+ txt=hnd2.FirstChild("MessageTrustLevel").FirstChild().ToText();\r
+ if(txt)\r
+ {\r
+ messagetruststr=txt->ValueStr();\r
+ StringFunctions::Convert(messagetruststr,messagetrust);\r
+ }\r
+ txt=hnd2.FirstChild("TrustListTrustLevel").FirstChild().ToText();\r
+ if(txt)\r
+ {\r
+ trustlisttruststr=txt->ValueStr();\r
+ StringFunctions::Convert(trustlisttruststr,trustlisttrust);\r
+ }\r
+\r
+ if(identity!="" && messagetrust>=0 && messagetrust<=100 && trustlisttrust>=0 && trustlisttrust<=100)\r
+ {\r
+ m_trust.push_back(trust(identity,messagetrust,trustlisttrust));\r
+ }\r
+ else\r
+ {\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,__FUNCTION__," malformed Trust in TrustList.xml");\r
+ }\r
+ \r
+ node=node->NextSibling("Trust");\r
+ }\r
+\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
PublicKey TEXT,\\r
PrivateKey TEXT,\\r
SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
+ PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
+ PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
LastInsertedIdentity DATETIME,\\r
InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
LastInsertedPuzzle DATETIME,\\r
InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
- LastInsertedTrustList DATETIME\\r
+ LastInsertedTrustList DATETIME,\\r
+ InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedBoardList DATETIME\\r
);");\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
InsertIndex INTEGER\\r
);");\r
\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\\r
+ LocalIdentityID INTEGER,\\r
+ Day DATE,\\r
+ InsertIndex INTEGER\\r
+ );");\r
+\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\\r
+ IdentityID INTEGER,\\r
+ Day DATE,\\r
+ RequestIndex INTEGER,\\r
+ Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
+ );");\r
+\r
db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\\r
UUID TEXT UNIQUE,\\r
LocalIdentityID INTEGER,\\r
PublicKey TEXT,\\r
Name TEXT,\\r
SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
+ PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
+ PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
DateAdded DATETIME,\\r
LastSeen DATETIME,\\r
LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
);");\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
- IdentityID INTEGER PRIMARY KEY,\\r
+ IdentityID INTEGER,\\r
Day DATE,\\r
RequestIndex INTEGER,\\r
Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
);");\r
\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\\r
+ IdentityID INTEGER,\\r
+ TargetIdentityID INTEGER,\\r
+ MessageTrust INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\\r
+ TrustListTrust INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100)\\r
+ );");\r
+\r
+ // calculates peer trust\r
+ db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
+ SELECT TargetIdentityID, \\r
+ ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \\r
+ ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\r
+ FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
+ WHERE LocalTrustListTrust>(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
+ GROUP BY TargetIdentityID;");\r
+\r
+ // update PeerTrustLevel when deleting a record from tblPeerTrust\r
+ db->Execute("CREATE TRIGGER trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
+ END;");\r
+\r
+ // update PeerTrustLevel when inserting a record into tblPeerTrust\r
+ db->Execute("CREATE TRIGGER trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
+ END;");\r
+\r
+ // update PeerTrustLevel when updating a record in tblPeerTrust\r
+ db->Execute("CREATE TRIGGER trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
+ UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
+ END;");\r
+\r
+ // recalculate all Peer TrustLevels when updating Local TrustLevels on tblIdentity - doesn't really need to be all, but rather all identities the updated identity has a trust level for. It's easier to update everyone for now.\r
+ db->Execute("CREATE TRIGGER trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
+ END;");\r
+\r
}\r
\r
void SetupDefaultOptions()\r
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"MaxTrustListRequests");\r
+ st.Bind(1,"5");\r
+ st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
+ st.Step();\r
+ st.Reset();\r
+\r
+ st.Bind(0,"MinLocalTrustListTrust");\r
+ st.Bind(1,"50");\r
+ st.Bind(2,"Specifies a local trust list trust level that a peer must have before its trust list will be included in the weighted average. Any peers below this number will be excluded from the results.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
}\r
\r
void SetupLogFile()\r
SetupDB();\r
SetupDefaultOptions();\r
\r
-\r
SetupLogFile();\r
\r
SetupNetwork();\r