X-Git-Url: https://git.pterodactylus.net/?p=fms.git;a=blobdiff_plain;f=src%2Ffreenet%2Fmessagerequester.cpp;h=5c95cdbbcdb9da3eb2e1123f14bf15e8a4dd4aa5;hp=c9908a5ecaefa20e22d35e8c40346d3891ff6d1a;hb=853f67b0b7b8121d572cff34d40f7b28cac8f65e;hpb=37a8d59548287dcad78ef00e7b18058721eb9935 diff --git a/src/freenet/messagerequester.cpp b/src/freenet/messagerequester.cpp index c9908a5..5c95cdb 100644 --- a/src/freenet/messagerequester.cpp +++ b/src/freenet/messagerequester.cpp @@ -1,6 +1,8 @@ #include "../../include/freenet/messagerequester.h" #include "../../include/freenet/messagexml.h" +#include + #ifdef XMEM #include #endif @@ -15,10 +17,12 @@ MessageRequester::MessageRequester(FCPv2 *fcp):IIndexRequester(fcp) Initialize(); } -const long MessageRequester::GetBoardID(const std::string &boardname) +const long MessageRequester::GetBoardID(const std::string &boardname, const std::string &identityname) { + std::string lowerboard=boardname; + StringFunctions::LowerCase(lowerboard,lowerboard); SQLite3DB::Statement st=m_db->Prepare("SELECT BoardID FROM tblBoard WHERE BoardName=?;"); - st.Bind(0,boardname); + st.Bind(0,lowerboard); st.Step(); if(st.RowReturned()) @@ -31,9 +35,18 @@ const long MessageRequester::GetBoardID(const std::string &boardname) { DateTime now; now.SetToGMTime(); - st=m_db->Prepare("INSERT INTO tblBoard(BoardName,DateAdded) VALUES(?,?);"); + st=m_db->Prepare("INSERT INTO tblBoard(BoardName,DateAdded,SaveReceivedMessages,AddedMethod) VALUES(?,?,?,?);"); st.Bind(0,boardname); st.Bind(1,now.Format("%Y-%m-%d %H:%M:%S")); + if(m_savemessagesfromnewboards) + { + st.Bind(2,"true"); + } + else + { + st.Bind(2,"false"); + } + st.Bind(3,"Message from "+identityname); st.Step(true); return st.GetLastInsertRowID(); } @@ -78,6 +91,9 @@ const bool MessageRequester::HandleAllData(FCPMessage &message) MessageXML xml; long identityid; long index; + bool inserted=false; + bool validmessage=true; + long savetoboardcount=0; StringFunctions::Split(message["Identifier"],"|",idparts); StringFunctions::Convert(message["DataLength"],datalength); @@ -112,54 +128,152 @@ const bool MessageRequester::HandleAllData(FCPMessage &message) if(xml.ParseXML(std::string(data.begin(),data.end()))==true) { std::vector boards=xml.GetBoards(); + std::map replyto=xml.GetInReplyTo(); + + if(boards.size()>m_maxboardspermessage) + { + boards.resize(m_maxboardspermessage); + } if(boards.size()<=0) { m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain any boards! "+message["Identifier"]); + // remove this identityid from request list + RemoveFromRequestList(idparts[1]); return true; } if(xml.GetReplyBoard()=="") { m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain a reply board! "+message["Identifier"]); + // remove this identityid from request list + RemoveFromRequestList(idparts[1]); return true; } - st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES(?,?,?,?,?,?,?,?);"); - st.Bind(0,identityid); - st.Bind(1,GetIdentityName(identityid)); - st.Bind(2,xml.GetDate()); - st.Bind(3,xml.GetTime()); - st.Bind(4,xml.GetSubject()); - st.Bind(5,xml.GetMessageID()); - st.Bind(6,GetBoardID(xml.GetReplyBoard())); - st.Bind(7,xml.GetBody()); - st.Step(true); - int messageid=st.GetLastInsertRowID(); - - st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);"); - for(std::vector::iterator i=boards.begin(); i!=boards.end(); i++) + // make sure the reply board is on the board list we are saving - if not, replace the last element of boards with the reply board + if(xml.GetReplyBoard()!="" && std::find(boards.begin(),boards.end(),xml.GetReplyBoard())==boards.end() && boards.size()>0) { - st.Bind(0,messageid); - st.Bind(1,GetBoardID((*i))); - st.Step(); - st.Reset(); + boards[boards.size()-1]=xml.GetReplyBoard(); } - st.Finalize(); - st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);"); - std::map replyto=xml.GetInReplyTo(); - for(std::map::iterator j=replyto.begin(); j!=replyto.end(); j++) + // make sure domain of message id match 43 characters of public key of identity (remove - and ~) - if not, discard message + // implement after 0.1.12 is released + st=m_db->Prepare("SELECT PublicKey FROM tblIdentity WHERE IdentityID=?;"); + st.Bind(0,identityid); + st.Step(); + if(st.RowReturned()) { - st.Bind(0,messageid); - st.Bind(1,(*j).second); - st.Bind(2,(*j).first); - st.Step(); - st.Reset(); + std::vector uuidparts; + std::vector keyparts; + std::string keypart=""; + std::string publickey=""; + + st.ResultText(0,publickey); + + StringFunctions::SplitMultiple(publickey,"@,",keyparts); + StringFunctions::SplitMultiple(xml.GetMessageID(),"@",uuidparts); + + if(uuidparts.size()>1 && keyparts.size()>1) + { + keypart=StringFunctions::Replace(StringFunctions::Replace(keyparts[1],"-",""),"~",""); + if(keypart!=uuidparts[1]) + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData MessageID in Message doesn't match public key of identity : "+message["Identifier"]); + validmessage=false; + } + } + else + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Error with identity's public key or Message ID : "+message["Identifier"]); + validmessage=false; + } + } + else + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Error couldn't find identity : "+message["Identifier"]); + validmessage=false; } - st.Finalize(); - m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]); + // make sure we will at least save to 1 board before inserting message + savetoboardcount=0; + for(std::vector::iterator bi=boards.begin(); bi!=boards.end(); bi++) + { + if(SaveToBoard((*bi))) + { + savetoboardcount++; + } + } + if(validmessage && savetoboardcount>0) + { + std::string nntpbody=""; + nntpbody=xml.GetBody(); + + //add file keys/sizes to body + std::vector fileattachments=xml.GetFileAttachments(); + if(fileattachments.size()>0) + { + nntpbody+="\r\nAttachments"; + } + for(std::vector::iterator i=fileattachments.begin(); i!=fileattachments.end(); i++) + { + std::string sizestr="0"; + StringFunctions::Convert((*i).m_size,sizestr); + + nntpbody+="\r\n"+(*i).m_key; + nntpbody+="\r\n"+sizestr+" bytes"; + nntpbody+="\r\n"; + } + + st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body,MessageIndex) VALUES(?,?,?,?,?,?,?,?,?);"); + st.Bind(0,identityid); + st.Bind(1,GetIdentityName(identityid)); + st.Bind(2,xml.GetDate()); + st.Bind(3,xml.GetTime()); + st.Bind(4,xml.GetSubject()); + st.Bind(5,xml.GetMessageID()); + st.Bind(6,GetBoardID(xml.GetReplyBoard(),GetIdentityName(identityid))); + st.Bind(7,nntpbody); + st.Bind(8,index); + inserted=st.Step(true); + int messageid=st.GetLastInsertRowID(); + + if(inserted==true) + { + + st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);"); + for(std::vector::iterator i=boards.begin(); i!=boards.end(); i++) + { + if(SaveToBoard((*i))) + { + st.Bind(0,messageid); + st.Bind(1,GetBoardID((*i),GetIdentityName(identityid))); + st.Step(); + st.Reset(); + } + } + st.Finalize(); + + st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);"); + for(std::map::iterator j=replyto.begin(); j!=replyto.end(); j++) + { + st.Bind(0,messageid); + st.Bind(1,(*j).second); + st.Bind(2,(*j).first); + st.Step(); + st.Reset(); + } + st.Finalize(); + + m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]); + + } + else // couldn't insert - was already in database + { + //m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAddData could not insert message into database. "+message["Identifier"]); + } + + } // if validmessage } else { @@ -231,6 +345,49 @@ void MessageRequester::Initialize() { m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MessageDownloadMaxDaysBackward is currently set at "+tempval+". This value might be incorrectly configured."); } + Option::Instance()->Get("MaxPeerMessagesPerDay",tempval); + StringFunctions::Convert(tempval,m_maxpeermessages); + if(m_maxpeermessages<1) + { + m_maxpeermessages=1; + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"Option MaxPeerMessagesPerDay is currently set at "+tempval+". It must be 1 or greater."); + } + if(m_maxpeermessages<20 || m_maxpeermessages>1000) + { + m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxPeerMessagesPerDay is currently set at "+tempval+". This value might be incorrectly configured. The suggested value is 200."); + } + Option::Instance()->Get("MaxBoardsPerMessage",tempval); + StringFunctions::Convert(tempval,m_maxboardspermessage); + if(m_maxboardspermessage<1) + { + m_maxboardspermessage=1; + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"Option MaxBoardsPerMessage is currently set at "+tempval+". It must be 1 or greater."); + } + if(m_maxboardspermessage>20) + { + m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxBoardsPerMessage is currently set at "+tempval+". This value might be incorrectly configured."); + } + + Option::Instance()->Get("SaveMessagesFromNewBoards",tempval); + if(tempval=="true") + { + m_savemessagesfromnewboards=true; + } + else + { + m_savemessagesfromnewboards=false; + } + + Option::Instance()->Get("LocalTrustOverridesPeerTrust",tempval); + if(tempval=="true") + { + m_localtrustoverrides=true; + } + else + { + m_localtrustoverrides=false; + } + } void MessageRequester::PopulateIDList() @@ -240,14 +397,26 @@ void MessageRequester::PopulateIDList() std::string val2; std::string val3; std::string sql; + long requestindex; date.SetToGMTime(); date.Add(0,0,0,-m_maxdaysbackward); sql="SELECT tblIdentity.IdentityID,Day,RequestIndex "; sql+="FROM tblMessageRequests INNER JOIN tblIdentity ON tblMessageRequests.IdentityID=tblIdentity.IdentityID "; - sql+="WHERE tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') AND FromMessageList='true' AND Found='false' AND Day>='"+date.Format("%Y-%m-%d")+"' "; - sql+="AND (tblIdentity.PeerMessageTrust IS NULL OR tblIdentity.PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) "; + sql+="WHERE FromMessageList='true' AND Found='false' AND Day>='"+date.Format("%Y-%m-%d")+"' "; + if(m_localtrustoverrides==false) + { + sql+="AND (tblIdentity.LocalMessageTrust IS NULL OR tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) "; + sql+="AND (tblIdentity.PeerMessageTrust IS NULL OR tblIdentity.PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) "; + } + else + { + sql+="AND (tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') OR (tblIdentity.LocalMessageTrust IS NULL AND (tblIdentity.PeerMessageTrust IS NULL OR tblIdentity.PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')))) "; + } + sql+="AND tblIdentity.Name <> '' "; + // sort by day descending - in case there is a bunch of messages on a day that keep timing out, we will eventually get to the next day and hopefully find messages there + sql+="ORDER BY tblMessageRequests.Day DESC "; sql+=";"; SQLite3DB::Statement st=m_db->Prepare(sql); @@ -260,15 +429,45 @@ void MessageRequester::PopulateIDList() st.ResultText(0,val1); st.ResultText(1,val2); st.ResultText(2,val3); - if(m_ids.find(val1+"*"+val2+"*"+val3)==m_ids.end()) + + requestindex=0; + StringFunctions::Convert(val3,requestindex); + + // only continue if index is < max messages we will accept from a peer + if(requestindexPrepare("SELECT SaveReceivedMessages FROM tblBoard WHERE BoardName=?;"); + st.Bind(0,boardname); + st.Step(); + if(st.RowReturned()) + { + std::string val=""; + st.ResultText(0,val); + if(val=="true") + { + save=true; + } + else + { + save=false; + } + } + return save; +} + void MessageRequester::StartRequest(const std::string &requestid) { FCPMessage message; @@ -297,10 +496,13 @@ void MessageRequester::StartRequest(const std::string &requestid) message["Identifier"]=m_fcpuniquename+"|"+requestid+"|"+parts[0]+"|"+parts[1]+"|"+parts[2]+"|"+message["URI"]; message["ReturnType"]="direct"; message["MaxSize"]="1000000"; // 1 MB + message["MaxRetries"]="-1"; // use ULPR since we are fairly sure message exists since the author says it does m_fcp->SendMessage(message); m_requesting.push_back(requestid); + + m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::StartRequest requesting "+message["Identifier"]); } m_ids[requestid]=true;