version 0.2.17
[fms.git] / src / freenet / trustlistinserter.cpp
1 #include "../../include/freenet/trustlistinserter.h"\r
2 #include "../../include/option.h"\r
3 #include "../../include/freenet/trustlistxml.h"\r
4 #include "../../include/stringfunctions.h"\r
5 \r
6 #ifdef XMEM\r
7         #include <xmem.h>\r
8 #endif\r
9 \r
10 TrustListInserter::TrustListInserter()\r
11 {\r
12         Initialize();\r
13 }\r
14 \r
15 TrustListInserter::TrustListInserter(FCPv2 *fcp):IFCPConnected(fcp)\r
16 {\r
17         Initialize();\r
18 }\r
19 \r
20 void TrustListInserter::CheckForNeededInsert()\r
21 {\r
22         DateTime date;\r
23         date.SetToGMTime();\r
24         int currentday=date.GetDay();\r
25         date.Add(0,0,-6);\r
26         // insert trust lists every 6 hours - if 6 hours ago was different day then set to midnight of current day to insert list today ASAP\r
27         if(currentday!=date.GetDay())\r
28         {\r
29                 date.Set(date.GetYear(),date.GetMonth(),currentday);\r
30         }\r
31         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
32 \r
33         if(rs.Empty()==false)\r
34         {\r
35                 StartInsert(rs.GetInt(0),rs.GetField(1));\r
36         }\r
37 }\r
38 \r
39 void TrustListInserter::FCPConnected()\r
40 {\r
41         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false';");\r
42 }\r
43 \r
44 void TrustListInserter::FCPDisconnected()\r
45 {\r
46 \r
47 }\r
48 \r
49 const bool TrustListInserter::HandleMessage(FCPMessage &message)\r
50 {\r
51 \r
52         if(message["Identifier"].find("TrustListInserter")==0)\r
53         {\r
54                 \r
55                 DateTime now;\r
56                 std::vector<std::string> idparts;\r
57 \r
58                 now.SetToGMTime();\r
59                 StringFunctions::Split(message["Identifier"],"|",idparts);\r
60 \r
61                 // no action for URIGenerated\r
62                 if(message.GetName()=="URIGenerated")\r
63                 {\r
64                         return true;\r
65                 }\r
66 \r
67                 // no action for IdentifierCollision\r
68                 if(message.GetName()=="IdentifierCollision")\r
69                 {\r
70                         return true;\r
71                 }\r
72 \r
73                 if(message.GetName()=="PutSuccessful")\r
74                 {\r
75                         // non USK\r
76                         if(idparts[0]=="TrustListInserter")\r
77                         {\r
78                                 m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false', LastInsertedTrustList='"+now.Format("%Y-%m-%d %H:%M:%S")+"' WHERE LocalIdentityID="+idparts[1]+";");\r
79                                 m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
80                                 m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"TrustListInserter::HandleMessage inserted TrustList xml");\r
81                         }\r
82                         return true;\r
83                 }\r
84 \r
85                 if(message.GetName()=="PutFailed" && idparts[0]=="TrustListInserter")\r
86                 {\r
87                         // non USK\r
88                         if(idparts[0]=="TrustListInserter")\r
89                         {\r
90                                 m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='false' WHERE LocalIdentityID="+idparts[1]+";");\r
91                                 m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"TrustListInserter::HandleMessage failure inserting TrustList xml.  Code="+message["Code"]+" Description="+message["CodeDescription"]);\r
92                         \r
93                                 // if code 9 (collision), then insert index into inserted table\r
94                                 if(message["Code"]=="9")\r
95                                 {\r
96                                         m_db->Execute("INSERT INTO tblTrustListInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
97                                 }\r
98                         }\r
99                         return true;\r
100                 }\r
101 \r
102         }\r
103 \r
104         return false;\r
105 }\r
106 \r
107 void TrustListInserter::Initialize()\r
108 {\r
109         Option::Instance()->Get("MessageBase",m_messagebase);\r
110         m_lastchecked.SetToGMTime();\r
111 }\r
112 \r
113 void TrustListInserter::Process()\r
114 {\r
115         DateTime now;\r
116         now.SetToGMTime();\r
117 \r
118         // check every minute\r
119         if(m_lastchecked<=(now-(1.0/1440.0)))\r
120         {\r
121                 CheckForNeededInsert();\r
122                 m_lastchecked=now;\r
123         }\r
124 }\r
125 \r
126 void TrustListInserter::RegisterWithThread(FreenetMasterThread *thread)\r
127 {\r
128         thread->RegisterFCPConnected(this);\r
129         thread->RegisterFCPMessageHandler(this);\r
130         thread->RegisterPeriodicProcessor(this);\r
131 }\r
132 \r
133 void TrustListInserter::StartInsert(const long localidentityid, const std::string &privatekey)\r
134 {\r
135         FCPMessage message;\r
136         TrustListXML xml;\r
137         std::string data;\r
138         std::string datasizestr;\r
139         std::string publickey;\r
140         int messagetrust;\r
141         int trustlisttrust;\r
142         DateTime now,date;\r
143         int index;\r
144         std::string indexstr;\r
145         std::string localidentityidstr;\r
146         std::string messagetrustcomment="";\r
147         std::string trustlisttrustcomment="";\r
148 \r
149         now.SetToGMTime();\r
150         date.SetToGMTime();\r
151 \r
152         // insert all identities not in trust list already\r
153         m_db->Execute("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) SELECT LocalIdentityID,IdentityID FROM tblLocalIdentity,tblIdentity WHERE LocalIdentityID || '_' || IdentityID NOT IN (SELECT LocalIdentityID || '_' || IdentityID FROM tblIdentityTrust);");\r
154 \r
155         // build the xml file - we only want to add identities that we recently saw, otherwise we could be inserting a ton of identities\r
156         date.Add(0,0,0,-20);    // identities seen in last 20 days\r
157         //SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey, LocalMessageTrust, LocalTrustListTrust, MessageTrustComment, TrustListTrustComment FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey<>'' AND LastSeen>=?;");\r
158         // we want to order by public key so we can't do identity correllation based on the sequence of identities in the list.\r
159         SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey, tblIdentityTrust.LocalMessageTrust, tblIdentityTrust.LocalTrustListTrust, tblIdentityTrust.MessageTrustComment, tblIdentityTrust.TrustListTrustComment FROM tblIdentity INNER JOIN tblIdentityTrust ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE PublicKey IS NOT NULL AND PublicKey<>'' AND LastSeen>=? AND tblIdentityTrust.LocalIdentityID=? ORDER BY PublicKey;");\r
160         st.Bind(0,date.Format("%Y-%m-%d"));\r
161         st.Bind(1,localidentityid);\r
162         st.Step();\r
163         while(st.RowReturned())\r
164         {\r
165                 st.ResultText(0,publickey);\r
166                 if(st.ResultNull(1)==false)\r
167                 {\r
168                         st.ResultInt(1,messagetrust);\r
169                 }\r
170                 else\r
171                 {\r
172                         messagetrust=-1;\r
173                 }\r
174                 if(st.ResultNull(2)==false)\r
175                 {\r
176                         st.ResultInt(2,trustlisttrust);\r
177                 }\r
178                 else\r
179                 {\r
180                         trustlisttrust=-1;\r
181                 }\r
182                 st.ResultText(3,messagetrustcomment);\r
183                 st.ResultText(4,trustlisttrustcomment);\r
184                 xml.AddTrust(publickey,messagetrust,trustlisttrust,messagetrustcomment,trustlisttrustcomment);\r
185                 st.Step();\r
186         }\r
187 \r
188         // get next insert index\r
189         st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblTrustListInserts WHERE LocalIdentityID=? AND Day=?;");\r
190         st.Bind(0,localidentityid);\r
191         st.Bind(1,now.Format("%Y-%m-%d"));\r
192         st.Step();\r
193 \r
194         index=0;\r
195         if(st.RowReturned() && st.ResultNull(0)==false)\r
196         {\r
197                 st.ResultInt(0,index);\r
198                 index++;\r
199         }\r
200 \r
201         StringFunctions::Convert(localidentityid,localidentityidstr);\r
202         StringFunctions::Convert(index,indexstr);\r
203 \r
204         data=xml.GetXML();\r
205         StringFunctions::Convert(data.size(),datasizestr);\r
206 \r
207         message.SetName("ClientPut");\r
208         message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|TrustList|"+indexstr+".xml";\r
209         message["Identifier"]="TrustListInserter|"+localidentityidstr+"|"+indexstr+"|"+message["URI"];\r
210         message["UploadFrom"]="direct";\r
211         message["DataLength"]=datasizestr;\r
212         m_fcp->SendMessage(message);\r
213         m_fcp->SendRaw(data.c_str(),data.size());\r
214 \r
215         // insert to USK\r
216         message.Reset();\r
217         message.SetName("ClientPutComplexDir");\r
218         message["URI"]="USK"+privatekey.substr(3)+m_messagebase+"|"+now.Format("%Y.%m.%d")+"|TrustList/0/";\r
219         message["Identifier"]="TrustListInserterUSK|"+message["URI"];\r
220         message["DefaultName"]="TrustList.xml";\r
221         message["Files.0.Name"]="TrustList.xml";\r
222         message["Files.0.UplaodFrom"]="direct";\r
223         message["Files.0.DataLength"]=datasizestr;\r
224         m_fcp->SendMessage(message);\r
225         m_fcp->SendRaw(data.c_str(),data.size());\r
226 \r
227         m_db->Execute("UPDATE tblLocalIdentity SET InsertingTrustList='true' WHERE LocalIdentityID="+localidentityidstr+";");\r
228 \r
229 }\r