689641fd8575d888e2a03ce5899a95998b269a37
[fms.git] / src / freenet / freenetmasterthread.cpp
1 #include "../../include/freenet/freenetmasterthread.h"\r
2 #include "../../include/option.h"\r
3 #include "../../include/uuidgenerator.h"\r
4 #include "../../include/stringfunctions.h"\r
5 #include "../../include/freenet/unkeyedidcreator.h"\r
6 #include "../../include/freenet/identityinserter.h"\r
7 #include "../../include/freenet/identityrequester.h"\r
8 #include "../../include/freenet/introductionpuzzleinserter.h"\r
9 #include "../../include/freenet/identityintroductionrequester.h"\r
10 #include "../../include/freenet/introductionpuzzlerequester.h"\r
11 #include "../../include/freenet/introductionpuzzleremover.h"\r
12 #include "../../include/freenet/identityintroductioninserter.h"\r
13 #include "../../include/freenet/trustlistinserter.h"\r
14 #include "../../include/freenet/trustlistrequester.h"\r
15 #include "../../include/freenet/messagelistrequester.h"\r
16 #include "../../include/freenet/messagerequester.h"\r
17 #include "../../include/freenet/messageinserter.h"\r
18 #include "../../include/freenet/messagelistinserter.h"\r
19 \r
20 #include <zthread/Thread.h>\r
21 \r
22 #ifdef XMEM\r
23         #include <xmem.h>\r
24 #endif\r
25 \r
26 FreenetMasterThread::FreenetMasterThread()\r
27 {\r
28         std::string fcpport;\r
29 \r
30         if(Option::instance()->Get("FCPHost",m_fcphost)==false)\r
31         {\r
32                 m_fcphost="localhost";\r
33                 Option::instance()->Set("FCPHost",m_fcphost);\r
34         }\r
35         if(Option::instance()->Get("FCPPort",fcpport)==false)\r
36         {\r
37                 fcpport="9481";\r
38                 Option::instance()->Set("FCPPort",fcpport);\r
39         }\r
40 \r
41         // convert fcp port to long, and make sure it's within the valid port range\r
42         if(StringFunctions::Convert(fcpport,m_fcpport)==false)\r
43         {\r
44                 m_fcpport=9481;\r
45                 Option::instance()->Set("FCPPort","9481");\r
46         }\r
47 \r
48         m_receivednodehello=false;\r
49 \r
50 }\r
51 \r
52 FreenetMasterThread::~FreenetMasterThread()\r
53 {\r
54 \r
55 }\r
56 \r
57 const bool FreenetMasterThread::FCPConnect()\r
58 {\r
59         // we were previosly connected, send FCPDisconnect to objects\r
60         if(m_receivednodehello==true)\r
61         {\r
62                 for(std::vector<IFCPConnected *>::iterator i=m_fcpconnected.begin(); i!=m_fcpconnected.end(); i++)\r
63                 {\r
64                         (*i)->FCPDisconnected();\r
65                 }\r
66                 m_receivednodehello=false;\r
67         }\r
68 \r
69         m_log->WriteLog(LogFile::LOGLEVEL_INFO,"FreenetMasterThread::FCPConnect trying to connect to node "+m_fcphost);\r
70 \r
71         if(m_fcp.Connect(m_fcphost.c_str(),m_fcpport)==true)\r
72         {\r
73                 UUIDGenerator uuid;\r
74                 std::string clientname="FMSClient-"+uuid.Generate();\r
75                 // send ClientHello message to node\r
76                 m_fcp.SendMessage("ClientHello",2,"Name",clientname.c_str(),"ExpectedVersion","2.0");\r
77 \r
78                 m_log->WriteLog(LogFile::LOGLEVEL_INFO,"FreenetMasterThread::FCPConnect connected to node");\r
79 \r
80                 return true;\r
81         }\r
82         else\r
83         {\r
84                 return false;\r
85         }\r
86 \r
87 }\r
88 \r
89 const bool FreenetMasterThread::HandleMessage(FCPMessage &message)\r
90 {\r
91         if(message.GetName()=="NodeHello")\r
92         {\r
93                 m_receivednodehello=true;\r
94 \r
95                 // send connected message to all objects, must do this AFTER we received the NodeHello message\r
96                 for(std::vector<IFCPConnected *>::iterator i=m_fcpconnected.begin(); i!=m_fcpconnected.end(); i++)\r
97                 {\r
98                         (*i)->FCPConnected();\r
99                 }\r
100 \r
101                 return true;\r
102         }\r
103         if(m_receivednodehello==true)\r
104         {\r
105                 bool handled=false;\r
106                 std::vector<IFCPMessageHandler *>::iterator i=m_fcpmessagehandlers.begin();\r
107                 while(handled==false && i!=m_fcpmessagehandlers.end())\r
108                 {\r
109                         handled=(*i)->HandleMessage(message);\r
110                         i++;\r
111                 }\r
112 \r
113                 if(handled==false)\r
114                 {\r
115                         std::string info("");\r
116                         for(std::map<std::string,std::string>::iterator mi=message.begin(); mi!=message.end(); mi++)\r
117                         {\r
118                                 info+="\t\t\t\t"+(*mi).first+"="+(*mi).second+"\r\n";\r
119                         }\r
120                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"FreenetMasterThread::HandleMessage received unhandled "+message.GetName()+" message.  Message content :\r\n"+info);\r
121 \r
122                         // if unhandled message was alldata - we must retrieve the data\r
123                         if(message.GetName()=="AllData")\r
124                         {\r
125                                 long length;\r
126                                 StringFunctions::Convert(message["DataLength"],length);\r
127                                 while(m_fcp.Connected() && m_fcp.ReceiveBufferSize()<length)\r
128                                 {\r
129                                         m_fcp.Update(1);\r
130                                 }\r
131                                 if(m_fcp.Connected())\r
132                                 {\r
133                                         char *data=new char[length];\r
134                                         m_fcp.ReceiveRaw(data,length);\r
135                                         delete [] data;\r
136                                 }\r
137                         }\r
138                 }\r
139 \r
140                 return handled;\r
141 \r
142         }\r
143         else\r
144         {\r
145                 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"FreenetMasterThread::HandleMessage received "+message.GetName()+" message before NodeHello");\r
146         }\r
147 \r
148         return false;\r
149 }\r
150 \r
151 void FreenetMasterThread::RegisterFCPConnected(IFCPConnected *obj)\r
152 {\r
153         m_fcpconnected.push_back(obj);\r
154 }\r
155 \r
156 void FreenetMasterThread::RegisterFCPMessageHandler(IFCPMessageHandler *obj)\r
157 {\r
158         m_fcpmessagehandlers.push_back(obj);\r
159 }\r
160 \r
161 void FreenetMasterThread::RegisterPeriodicProcessor(IPeriodicProcessor *obj)\r
162 {\r
163         m_processors.push_back(obj);\r
164 }\r
165 \r
166 void FreenetMasterThread::run()\r
167 {\r
168 \r
169         FCPMessage message;\r
170         bool done=false;\r
171 \r
172         Setup();\r
173 \r
174         do\r
175         {\r
176                 if(m_fcp.Connected()==false)\r
177                 {\r
178                         if(FCPConnect()==false)\r
179                         {\r
180 \r
181                                 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"FreenetMasterThread::run could not connect to node.  Waiting 60 seconds.");\r
182 \r
183                                 // wait 60 seconds - will then try to connect again\r
184                                 try\r
185                                 {\r
186                                         ZThread::Thread::sleep(60000);\r
187                                 }\r
188                                 catch(...)\r
189                                 {\r
190                                         done=true;\r
191                                 }\r
192                         }\r
193                 }\r
194                 // fcp is connected\r
195                 else\r
196                 {\r
197                         m_fcp.Update(1);\r
198 \r
199                         // check for message on receive buffer and handle it\r
200                         if(m_fcp.ReceiveBufferSize()>0)\r
201                         {\r
202                                 message.Reset();\r
203                                 message=m_fcp.ReceiveMessage();\r
204 \r
205                                 if(message.GetName()!="")\r
206                                 {\r
207                                         HandleMessage(message);\r
208                                 }\r
209                         }\r
210 \r
211                         // let objects do their processing\r
212                         for(std::vector<IPeriodicProcessor *>::iterator i=m_processors.begin(); i!=m_processors.end(); i++)\r
213                         {\r
214                                 (*i)->Process();\r
215                         }\r
216 \r
217                 }\r
218         }while(!ZThread::Thread::interrupted() && done==false);\r
219 \r
220         m_fcp.Disconnect();\r
221 \r
222         Shutdown();\r
223 \r
224 }\r
225 \r
226 void FreenetMasterThread::Setup()\r
227 {\r
228 \r
229         // seed random number generator\r
230         srand(time(NULL));\r
231 \r
232         m_registrables.push_back(new UnkeyedIDCreator(&m_fcp));\r
233         m_registrables.push_back(new IdentityInserter(&m_fcp));\r
234         m_registrables.push_back(new IdentityRequester(&m_fcp));\r
235         m_registrables.push_back(new IntroductionPuzzleInserter(&m_fcp));\r
236         m_registrables.push_back(new IdentityIntroductionRequester(&m_fcp));\r
237         m_registrables.push_back(new IntroductionPuzzleRequester(&m_fcp));\r
238         m_registrables.push_back(new IntroductionPuzzleRemover());\r
239         m_registrables.push_back(new IdentityIntroductionInserter(&m_fcp));\r
240         m_registrables.push_back(new TrustListInserter(&m_fcp));\r
241         m_registrables.push_back(new TrustListRequester(&m_fcp));\r
242         m_registrables.push_back(new MessageListRequester(&m_fcp));\r
243         m_registrables.push_back(new MessageRequester(&m_fcp));\r
244         m_registrables.push_back(new MessageInserter(&m_fcp));\r
245         m_registrables.push_back(new MessageListInserter(&m_fcp));\r
246 \r
247         for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
248         {\r
249                 (*i)->RegisterWithThread(this);\r
250         }\r
251 \r
252 }\r
253 \r
254 void FreenetMasterThread::Shutdown()\r
255 {\r
256         // delete each registrable object\r
257         for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
258         {\r
259                 delete (*i);\r
260         }\r
261 }\r