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