]> git.mxchange.org Git - hub.git/blob - application/hub/main/class_HubCoreLoop.php
Code base merged from ship-simu repos
[hub.git] / application / hub / main / class_HubCoreLoop.php
1 <?php
2 /**
3  * The hub's main loop. The hub will wait and listen for incoming requests in
4  * this loop.
5  *
6  * @author              Roland Haeder <webmaster@ship-simu.org>
7  * @version             0.0
8  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
9  * @license             GNU GPL 3.0 or any newer version
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24 class HubCoreLoop extends BaseFrameworkSystem {
25         /**
26          * Wether the hub is active and running
27          */
28         private $hubActivated = false;
29
30         /**
31          * Wether the hub is shutting down
32          */
33         private $hubShutsDown = false;
34
35         /**
36          * A list of all connected peers (sockets)
37          */
38         private $connectedPeers = null;
39
40         /**
41          * A console output handler
42          */
43         private $outputInstance = null;
44
45         /**
46          * Reading peers
47          */
48         private $readPeers = array();
49
50         /**
51          * Writing peers
52          */
53         private $writePeers = array();
54
55         /**
56          * The main socket (listening) for this hub
57          */
58         private $main_socket = null;
59
60         /**
61          * A list of authenticated peers
62          */
63         private $authPeers = null;
64
65         /**
66          * Last peer instance
67          */
68         private $lastPeerInstance = null;
69
70         /**
71          * Wether this hub is a master hub
72          */
73         private $hubIsMaster = false;
74
75         /**
76          * Maximum auth retries (cached)
77          */
78         private $authRetries = 0;
79
80         /**
81          * Auth request message
82          */
83         private $authRequest = "";
84
85         /**
86          * Cached timeout for auth requests
87          */
88         private $authRequestTimeout = 0;
89
90         /**
91          * An instance to the HubConnector class for master hub connection
92          */
93         private $masterConnector = null;
94
95         // Exception codes
96         const EXCEPTION_SOCKET_PROBLEM                  = 0xb00;
97         const EXCEPTION_HUB_PEER_TIMEOUT                = 0xb01;
98         const EXCEPTION_HUB_PEER_FAILED_AUTH    = 0xb02;
99         const EXCEPTION_HELLO_TIMED_OUT                 = 0xb03;
100
101         /**
102          * The private constructor
103          *
104          * @return      void
105          */
106         protected function __construct () {
107                 // Call parent constructor
108                 parent::__construct(__CLASS__);
109
110                 // Set description
111                 $this->setObjectDescription("Hub-Core Loop");
112
113                 // Set unique ID
114                 $this->generateUniqueId();
115
116                 // Tidy up a little
117                 $this->removeSystemArray();
118                 $this->removeNumberFormaters();
119
120                 // Init the peer list
121                 $this->initPeerList();
122         }
123
124         /**
125          * Factory for main loop
126          *
127          * @return      $hubInstance            An instance of this class
128          */
129         public final static function createHubCoreLoop () {
130                 // Get an instance
131                 $hubInstance = new HubCoreLoop();
132
133                 // Try to setup the socket
134                 $hubInstance->setupHub();
135
136                 // Get the configuration variable
137                 $outEngine = $hubInstance->getConfigInstance()->readConfig("tpl_engine");
138
139                 // Setup the console output handler
140                 $eval = sprintf("\$hubInstance->setOutputInstance(%s::create%s(\"%s\"));",
141                         $outEngine,
142                         $outEngine,
143                         $hubInstance->getConfigInstance()->readConfig("web_content_type")
144                 );
145
146                 // Debug message
147                 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $hubInstance->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: %s",
148                         $hubInstance->__toString(),
149                         htmlentities($eval)
150                 ));
151                 @eval($eval);
152
153                 // Return the prepared instance
154                 return $hubInstance;
155         }
156
157         /**
158          * Initializes the peer list
159          *
160          * @return      void
161          */
162         private final function initPeerList () {
163                 $this->connectedPeers = new FrameworkArrayObject("FakedConnectedPeers");
164                 $this->authPeers      = new FrameworkArrayObject("FakeAuthPeers");
165         }
166
167         /**
168          * Get total number of connected peers
169          *
170          * @return      $num            The total number of connected peers
171          */
172         private final function getTotalConnectedPeers () {
173                 $read = array($this->connectedPeers->getIterator()->current());
174                 $write = array();
175                 $except = array();
176
177                 // Get socket number
178                 $num = socket_select(
179                         $read,
180                         $write,
181                         $except,
182                         0
183                 );
184
185                 // Transfer readers and writers
186                 $this->readPeers        = $read;
187                 $this->writePeers       = $write;
188
189                 // Return the number
190                 return $num;
191         }
192
193         /**
194          * Handle newly connected peers
195          *
196          * @return      void
197          */
198         private final function handleNewPeers () {
199                 // Output message
200                 $this->getOutputInstance()->output(sprintf("[%s] Validating peer...", __METHOD__));
201
202                 // Is the main socket in the array?
203                 if (in_array($this->main_socket, $this->readPeers)) {
204                         // Accept the connection and add him to the list
205                         $peer_socket = socket_accept($this->main_socket);
206
207                         // Get a new peer instance
208                         $this->setCurrPeerInstance(HubPeer::createHubPeerBySocket($peer_socket, $this));
209
210                         // Register the new peer
211                         $this->getOutputInstance()->output(sprintf("[%s] Registering new peer with IP %s.",
212                                 __METHOD__,
213                                 $this->getCurrPeerInstance()->getValidatedIP()
214                         ));
215                         $this->connectedPeers->append($this->lastPeerInstance);
216
217                         // A new peer has connected
218                         $this->getOutputInstance()->output(sprintf("[%s] New peer with IP %s has been registered.",
219                                 __METHOD__,
220                                 $this->getCurrPeerInstance()->getValidatedIP()
221                         ));
222
223                         // Remove him from the list
224                         $key = array_search($this->main_socket, $this->readPeers);
225                         unset($this->readPeers[$key]);
226                 } // END - if
227         }
228
229         /**
230          * Handles unauthenticated peers
231          *
232          * @return      void
233          * @throws      HubPeerTimeoutException                 If the peer times out to answer a request
234          * @throws      HubPeerAuthorizationException           If the peer fails to authorize himself (to many retries)
235          */
236         private final function handleUnauthPeers () {
237                 // Are there some peers?
238                 if ($this->connectedPeers->count() > 1) {
239                         // Iterate through all connected peers
240                         for ($idx = $this->connectedPeers->getIterator(); $idx->valid(); $idx->next()) {
241                                 // Get current peer
242                                 $this->lastPeerInstance = $idx->current();
243
244                                 // Ignore own socket and invalid entries
245                                 if (($this->getCurrPeerInstance() !== $this->main_socket) && (is_object($this->getCurrPeerInstance())) && ($this->getCurrPeerInstance() instanceof HubPeer)) {
246                                         // Is this peer already authorized or is this the master hub?
247                                         // If this is the master hub then there is no auth required
248                                         if ((!$this->getCurrPeerInstance()->ifPeerIsAuthorized()) && (!$this->getCurrPeerInstance()->ifPeerIsLocalAdmin()) && (!$this->hubIsMaster)) {
249                                                 // This peer waits for authorization, so does he have some tries left?
250                                                 if ($this->getCurrPeerInstance()->getAuthRetries() <= $this->authRetries) {
251                                                         // This peer is still allowed to try his authorization
252                                                         if ($this->getCurrPeerInstance()->getLastSentMessage() == $this->authRequest) {
253                                                                 // Already asked so maybe timed out?
254                                                                 if ((time() - $this->getCurrPeerInstance()->getLastSentMessageStamp()) >= $this->authRequestTimeout) {
255                                                                         // Timed out so disconnect the peer
256                                                                         throw new HubPeerTimeoutException (
257                                                                                 array(
258                                                                                         'this'  => $this,
259                                                                                         'peer'  => $this->getCurrPeerInstance()
260                                                                                 ), self::EXCEPTION_HUB_PEER_TIMEOUT
261                                                                         );
262                                                                 } // END - if
263                                                         } elseif ($this->getCurrPeerInstance()->ifHelloReceived()) {
264                                                                 // HELLO received so we need to sent the AUTH request
265                                                                 $this->getCurrPeerInstance()->askAuthorizationKey();
266                                                         }
267                                                 } else {
268                                                         // This peer needs disconnecting!
269                                                         throw new HubPeerAuthorizationException (
270                                                                 array(
271                                                                         'this'  => $this,
272                                                                         'peer'  => $this->getCurrPeerInstance(),
273                                                                         'max'   => $this->authRetries
274                                                                 ), self::EXCEPTION_HUB_PEER_FAILED_AUTH
275                                                         );
276                                                 } // END - else
277                                         } elseif ((!$this->getCurrPeerInstance()->ifPeerIsAuthorized()) && ($this->getCurrPeerInstance()->ifPeerIsLocalAdmin())) {
278                                                 // This peer is a local admin so he is always authorized!
279                                                 $this->getCurrPeerInstance()->enableLocalAdmin();
280
281                                                 // Output debug message
282                                                 $this->getOutputInstance()->output(sprintf("[%s] A local admin has connected.",
283                                                         $this->__toString()
284                                                 ));
285
286                                                 // Say "hi" to the admin
287                                                 $this->getCurrPeerInstance()->sayHi2Admin();
288                                         } elseif (($this->hubIsMaster) && ($this->getCurrPeerInstance()->ifHelloReceived()) && (!$this->getCurrPeerInstance()->ifELHOsent())) {
289                                                 // Is the master hub so authorize the peer here...
290                                                 $this->getCurrPeerInstance()->enableIsAuthorized();
291                                                 $this->authPeers->append($this->getCurrPeerInstance());
292
293                                                 // Reply the HELLO request
294                                                 $this->getCurrPeerInstance()->replyHelloMessage();
295                                         }
296                                 } // END - if
297                         } // END - for
298                 } // END - if
299         }
300
301         /**
302          * Handles only authorized peers
303          *
304          * @return      void
305          */
306         public function handleAuthPeers () {
307                 // Are there some peers?
308                 if (($this->connectedPeers->count() > 1) && ($this->authPeers->count() > 0)) {
309                         // Iterate through all connected peers
310                         for ($idx = $this->authPeers->getIterator(); $idx->valid(); $idx->next()) {
311                                 // Get current peer
312                                 $this->lastPeerInstance = $idx->current();
313
314                                 // Do the ping and update our authPeer list (LATER!)
315                                 $this->lastPeerInstance->handlePingPeer();
316
317                                 // Avoids a notice...
318                                 if (is_null($this->getCurrPeerInstance())) break;
319                         } // END - for
320                 } // END - for
321         }
322
323         /**
324          * Setup the hub: Create a socket for listening on incoming requests,
325          * try to bind to a port, etc.
326          *
327          * @return      void
328          * @throws      SocketCreationException         If a socket cannot be created
329          * @throws      SocketSetupException            If a socket cannot be setuped
330          * @throws      SocketBindException                     If a socket cannot be bind to
331          *                                                                      an address and port
332          * @throws      SocketListeningException                If listening to a socket fails
333          */
334         private final function setupHub () {
335                 // Create a new TCP socket
336                 $main_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
337
338                 // Was it a success?
339                 if (!is_resource($main_socket)) {
340                         // This fails! :(
341                         throw new SocketCreationException(
342                                 array(
343                                         'this' => $this,
344                                         'code' => socket_last_error()
345                                 ), self::EXCEPTION_SOCKET_PROBLEM
346                         );
347                 }
348
349                 // Set socket options
350                 if (!socket_set_option($main_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
351                         // Close the socket
352                         $this->closeSocket($main_socket);
353
354                         // Problems setting socket options
355                         throw new SocketSetupException (
356                                 array(
357                                         'this' => $this,
358                                         'code' => socket_last_error()
359                                 ), self::EXCEPTION_SOCKET_PROBLEM
360                         );
361                 }
362
363                 // Set to non-blocking
364                 socket_set_nonblock($main_socket);
365
366                 // Bind the socket to an address
367                 if (!socket_bind($main_socket, $this->getConfigInstance()->readConfig("hub_listen_addr"), $this->getConfigInstance()->readConfig("hub_listen_port"))) {
368                         // Bind failed
369                         throw new SocketBindException (
370                                 array(
371                                         'this' => $this,
372                                         'host' => $this->getConfigInstance()->readConfig("hub_listen_addr"),
373                                         'port' => $this->getConfigInstance()->readConfig("hub_listen_port"),
374                                         'code' => socket_last_error()
375                                 ), self::EXCEPTION_SOCKET_PROBLEM
376                         );
377                 }
378
379                 // Listen to ... the socket ;-)
380                 if (!socket_listen($main_socket)) {
381                         // Opps, that didn't work. Next time better listen to your heart... Roxette
382                         throw new SocketListeningException(
383                                 array(
384                                         'this' => $this,
385                                         'code' => socket_last_error()
386                                 ), self::EXCEPTION_SOCKET_PROBLEM
387                         );
388                 }
389
390                 // Ignore user abort and do not time out
391                 @set_time_limit(0);
392                 @ignore_user_abort(true);
393
394                 // Cache more configuration stuff
395                 $this->authRetries        = $this->getConfigInstance()->readConfig("hub_max_auth_tries");
396                 $this->authRequest        = $this->getConfigInstance()->readConfig("hub_auth_request");
397                 $this->authRequestTimeout = $this->getConfigInstance()->readConfig("hub_auth_request_timeout");
398
399                 // The hub is running now!
400                 $this->hubActivated = true;
401
402                 // Append the main hub
403                 $this->main_socket = $main_socket;
404                 $this->connectedPeers->append($main_socket);
405         }
406
407         /**
408          * Removes the current peer from the list
409          *
410          * @return      void
411          */
412         public final function removePeerFromConnectList () {
413                 // Iterate through all connected peers
414                 for ($idx = $this->connectedPeers->getIterator(); $idx->valid(); $idx->next()) {
415                         // Get current peer from list
416                         $peer = $idx->current();
417
418                         // Is it a peer instance?
419                         if (($peer !== $this->main_socket) && (is_object($peer)) && ($peer instanceof HubPeer)) {
420                                 // Okay, we have a peer instance so is it the same?
421                                 if ($this->getCurrPeerInstance()->equals($peer)) {
422                                         // Remove him!
423                                         $idx->offsetUnset($idx->key());
424
425                                         // Remove the last instance as well
426                                         $this->lastPeerInstance = null;
427
428                                         // Remove the socket as well
429                                         $this->removeSocket($peer);
430
431                                         // Stop searching here
432                                         break;
433                                 }
434                         }
435                 }
436         }
437
438         /**
439          * Getter for console output handler
440          *
441          * @return      $outputInstance An instance of the output handler
442          */
443         public final function getOutputInstance () {
444                 return $this->outputInstance;
445         }
446
447         /**
448          * Setter for console output handler
449          *
450          * @param               $outputInstance An instance of the output handler
451          */
452         public final function setOutputInstance ($outputInstance) {
453                 $this->outputInstance = $outputInstance;
454         }
455
456         /**
457          * Getter for current peer instance to HubPeer class
458          *
459          * @return      $lastPeerInstance               Last peer instance
460          */
461         public final function getCurrPeerInstance () {
462                 return $this->lastPeerInstance;
463         }
464
465         /**
466          * Setter for current peer instance to HubPeer class
467          *
468          * @param               $lastPeerInstance               Last peer instance
469          * @return      void
470          */
471         public final function setCurrPeerInstance (HubPeer $lastPeerInstance) {
472                 $this->lastPeerInstance = $lastPeerInstance;
473         }
474
475         /**
476          * Checks wether the hub is running and not in shutdown phase
477          *
478          * @return      $isRunning      If the hub is running and not in shutdown phase
479          */
480         public function ifHubIsRunning () {
481                 return ((($this->hubActivated) || (!$this->hubShutsDown)) && ($this->connectedPeers->count() > 0));
482         }
483
484         /**
485          * Output the intro text
486          *
487          * @return      void
488          */
489         public final function outputIntro () {
490                 if ($this->getConfigInstance()->readConfig("hub_intro_enabled") == "Y") {
491                         // Output intro text
492                         $this->getOutputInstance()->output(sprintf("%s v%s Copyright (c) 2007, 2008 by Roland H&auml;der",
493                                 ApplicationHelper::getInstance()->getAppName(),
494                                 ApplicationHelper::getInstance()->getAppVersion()
495                         ));
496                         $this->getOutputInstance()->output("");
497                         $this->getOutputInstance()->output("This software is free software licensed under the GNU GPL. In telnet session enter &quot;/license&quot; to read the license.");
498                         $this->getOutputInstance()->output("This software uses the MXChange Framework, Copyright (c) 2007, 2008 by Roland H&auml;der which is licensed under the GNU GPL.");
499                         $this->getOutputInstance()->output("Enter &quot;/framework&quot; in telnet session to read that license.");
500                         $this->getOutputInstance()->output("");
501                         $this->getOutputInstance()->output("All core systems are initialized. Input on *this* console will currently be ignored!");
502                         $this->getOutputInstance()->output("");
503                         $this->getOutputInstance()->output(sprintf("[%s] Listening on: %s:%d",
504                                 $this->__toString(),
505                                 $this->getConfigInstance()->readConfig("hub_listen_addr"),
506                                 $this->getConfigInstance()->readConfig("hub_listen_port")
507                         ));
508                         $this->getOutputInstance()->output("----------------------------------------------------------------------------------------------------------------------------");
509                 }
510         }
511
512         /**
513                 * Do the main loop
514                 *
515                 * @return       void
516                 * @throws       SocketCreationException         If the main socket is not a resource
517                 */
518          public function coreLoop () {
519                 // Is the main socket vailid?
520                 if (!is_resource($this->main_socket)) {
521                         // Is not valid!
522                         throw new SocketCreationException(
523                                 array(
524                                         'this'  => $this,
525                                         'code'  => socket_last_error()
526                                 ), self::EXCEPTION_SOCKET_PROBLEM
527                         );
528                 } // END - if
529
530                 // We are ready to serve requests
531                 $this->getOutputInstance()->output(sprintf("[%s] Ready to serve requests.",
532                         $this->__toString()
533                 ));
534
535                 // Wait until the hub is shutting down
536                 while ($this->ifHubIsRunning()) {
537                         // Get number of total connected peers
538                         $num = $this->getTotalConnectedPeers();
539
540                         try {
541                                 // Handle the master hub connection
542                                 if ($this->masterConnector instanceof HubConnector) {
543                                         $this->masterConnector->handleMasterRequests();
544                                 }
545
546                                 // Check for unauthorized peers
547                                 $this->handleUnauthPeers();
548
549                                 // Handle authorized peers
550                                 $this->handleAuthPeers();
551                         } catch (HubPeerAuthorizationException $e) {
552                                 // Authorization has failed
553                                 $this->disconnectPeerWithReason("hub_msg_auth_tries");
554
555                                 // Get new total connected peers
556                                 $num = $this->getTotalConnectedPeers();
557                         } catch (HubPeerTimeoutException $e) {
558                                 // Disconnect and remove the peer
559                                 $this->disconnectPeerWithReason("hub_msg_auth_reply_timeout");
560
561                                 // Get new total connected peers
562                                 $num = $this->getTotalConnectedPeers();
563                         } catch (HubMasterDisconnectedException $e) {
564                                 // The master hub has disconnected us... :(
565                                 $this->masterConnector = null;
566                                 $this->getOutputInstance()->output(sprintf("[%s] The master has disconnected us. Reason given: %s",
567                                         $this->__toString(),
568                                         $e->getMessage()
569                                 ));
570
571                                 // Get new total connected peers
572                                 $num = $this->getTotalConnectedPeers();
573                         } catch (BrokenPipeException $e) {
574                                 // Broken pipes are bad for us... :(
575                                 $this->removePeerFromConnectList();
576                                 $this->getOutputInstance()->output(sprintf("[%s] A peer has closed the connection unexpected: %s",
577                                         $this->__toString(),
578                                         $e->getMessage()
579                                 ));
580
581                                 // Get new total connected peers
582                                 $num = $this->getTotalConnectedPeers();
583                         } catch (FrameworkException $e) {
584                                 // Catch all other exceptions and output them
585                                 hub_exception_handler($e);
586
587                                 // Get new total connected peers
588                                 $num = $this->getTotalConnectedPeers();
589                         }
590
591                         // Are there some peers?
592                         if ($num < 1) {
593                                 // Wait for more peers
594                                 continue;
595                         } // END - if
596
597                         // A new peer has connected
598                         $this->getOutputInstance()->output(sprintf("[%s] A new peer is connecting.",
599                                 $this->__toString()
600                         ));
601
602                         try {
603                                 // Check for new peers
604                                 $this->handleNewPeers();
605                         } catch (IPSpoofingException $e) {
606                                 // Output message
607                                 $this->getOutputInstance()->output(sprintf("[%s] The peer's IP number has changed!",
608                                         $this->__toString()
609                                 ));
610
611                                 // Output debug message
612                                 $this->getDebugInstance()->output(sprintf("[%s] Peer spoofes IP number: %s",
613                                         $this->__toString(),
614                                         $e->getMessage()
615                                 ));
616
617                                 // Disconnect the peer first
618                                 $this->disconnectPeerWithReason("hub_msg_spoofing");
619
620                                 // Get new total connected peers
621                                 $num = $this->getTotalConnectedPeers();
622                         } catch (FrameworkException $e) {
623                                 // Catch all exceptions and output them to avoid aborting the program unexpectly
624                                 hub_exception_handler($e);
625
626                                 // Get new total connected peers
627                                 $num = $this->getTotalConnectedPeers();
628                         }
629
630                 } // END - while
631         }
632
633         /**
634          * Tries to contact the master server or simply reports that we are the master server
635          *
636          * @return      void
637          */
638         public function contactMasterHub () {
639                 // Checks wether we are the master hub
640                 if ($_SERVER['SERVER_ADDR'] == $this->getConfigInstance()->readConfig("hub_master_ip")) {
641                         // We are master!
642                         $this->hubIsMaster = true;
643                         $this->getOutputInstance()->output(sprintf("[%s] Our IP %s matches the master IP. Becoming master hub...",
644                                 $this->__toString(),
645                                 $_SERVER['SERVER_ADDR']
646                         ));
647                 } else {
648                         // A regular hub or ultra hub so let's contact the master
649                         $this->getOutputInstance()->output(sprintf("[%s] Contacting the master hub at %s:%d...",
650                                 $this->__toString(),
651                                 $this->getConfigInstance()->readConfig("hub_master_ip"),
652                                 $this->getConfigInstance()->readConfig("hub_master_port")
653                         ));
654
655                         // Try to aquire a connection to the master...
656                         try {
657                                 // Announce us to the master hub
658                                 $this->announceToMasterHub();
659                         } catch (FrameworkException $e) {
660                                 // Catch all exceptions and output them
661                                 hub_exception_handler($e);
662                         }
663                 } // END - else
664         }
665
666         /**
667          * Disconnects the current with a configurable reason
668          *
669          * @param               $reasonEntry    The entry with the disconnection reason aka. message to the peer
670          * @return      void
671          */
672          public function disconnectPeerWithReason ($reasonEntry) {
673                 // Default is that we cannot read the peer's IP number
674                 $ip = "0.0.0.0";
675
676                 // Try to disconnect here
677                 try {
678                         // First get the raw IP number
679                         $ip = $this->getCurrPeerInstance()->getValidatedIP();
680
681                         // Disconnect the peer...
682                         $this->getCurrPeerInstance()->disconnectWithReason($this->getConfigInstance()->readConfig($reasonEntry));
683                 } catch (FrameworkException $e) {
684                         // Catch all exceptions and output them
685                         hub_exception_handler($e);
686                 }
687
688                 // Remove him from the list anyway
689                 $this->removePeerFromConnectList();
690
691                 // Output the message
692                 $this->getOutputInstance()->output(sprintf("[%s] Peer %s has been disconnected.",
693                         $this->__toString(),
694                         $ip
695                 ));
696         }
697
698         /**
699          * Announces this hub to the master hub. This is being done by connecting to it and asking for auth request
700          *
701          * @return      void
702          */
703         public function announceToMasterHub () {
704                 try {
705                         // Create a new instance for communicating to the master hub
706                         $this->masterConnector = HubConnector::createHubConnectorByAddressPort(
707                                 $this->getConfigInstance()->readConfig("hub_master_ip"),
708                                 $this->getConfigInstance()->readConfig("hub_master_port"),
709                                 $this
710                         );
711
712                         // Send all our accepted objects to the master hub
713                         $this->masterConnector->sendAllAcceptedObjects();
714                 } catch (SocketConnectException $e) {
715                         // The master hub is down!
716                         ApplicationEntryPoint::app_die($e->getMessage());
717                 }
718         }
719
720         /**
721          * Removes a given peer instance (socket) from all lists
722          *
723          * @param       $peerInstance           An instance of a HubPeer class
724          * @return      void
725          */
726         private function removeSocket (HubPeer $peerInstance) {
727                 // Get socket from peer
728                 $socket = $peerInstance->getPeerSocket();
729
730                 // Search for readers
731                 $key = array_search($socket, $this->readPeers, true);
732                 if ($key !== false) {
733                         // Remove from reader list
734                         unset($this->readPeers[$key]);
735                 }
736
737                 // Search for writers
738                 $key = array_search($socket, $this->writePeers, true);
739                 if ($key !== false) {
740                         // Remove from writer list
741                         unset($this->writePeers[$key]);
742                 }
743
744                 // Remove from auth peers as well
745                 for ($idx = $this->authPeers->getIterator(); $idx->valid(); $idx->next()) {
746                         // Get current entry
747                         $current = $idx->current();
748
749                         // Is it the same?
750                         if ($current->equals($peerInstance)) {
751                                 // Remove from auth (-awaiting) list
752                                 $idx->offsetUnset($idx->key());
753                                 break;
754                         }
755                 }
756         }
757
758 } // END - class
759
760 // [EOF]
761 ?>