1 /* Copyright (c) 2015, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #ifndef GCS_XCOM_UTILS_INCLUDED
24 #define GCS_XCOM_UTILS_INCLUDED
25
26 #include "xplatform/my_xp_thread.h"
27 #include "xplatform/my_xp_mutex.h"
28 #include "xplatform/my_xp_cond.h"
29 #include "xplatform/my_xp_util.h"
30
31 #include "gcs_member_identifier.h"
32 #include "gcs_group_identifier.h"
33 #include "gcs_types.h"
34 #include "gcs_xcom_group_member_information.h"
35
36 #include "simset.h"
37 #include "xcom_vp.h"
38 #include "xcom_common.h"
39 #include "node_list.h"
40 #include "node_set.h"
41 #include "task.h"
42 #include "server_struct.h"
43 #include "xcom_detector.h"
44 #include "site_struct.h"
45 #include "site_def.h"
46 #include "xcom_transport.h"
47 #include "xcom_base.h"
48 #include "task_net.h"
49 #include "node_connection.h"
50 #include "node_no.h"
51
52 #include <vector>
53 #include <string>
54
55 #define XCOM_COMM_STATUS_UNDEFINED -1
56
57 /**
58 @class gcs_xcom_utils
59
60 Class where the common binding utilities reside as static methods.
61 */
62 class Gcs_xcom_utils
63 {
64 public:
65 /**
66 Create a xcom group identifier from a Group Identifier.
67
68 @param[in] group_id A group identifier
69
70 @return an hash of the group identifier string that will serve as input
71 for the group id in XCom
72 */
73 static u_long build_xcom_group_id(Gcs_group_identifier &group_id);
74
75 /**
76 Processes a list of comma separated peer nodes.
77
78 @param peer_nodes input string of comma separated peer nodes
79 @param[out] processed_peers the list of configured peers
80 */
81 static
82 void process_peer_nodes(const std::string *peer_nodes,
83 std::vector<std::string> &processed_peers);
84
85 /**
86 Validates peer nodes according with IP/Address rules enforced by
87 is_valid_hostname function
88
89 @param [in,out] peers input list of peer nodes. It will be cleansed of
90 invalid peers
91 @param [in,out] invalid_peers This list will contain all invalid peers.
92 */
93 static
94 void validate_peer_nodes(std::vector<std::string> &peers,
95 std::vector<std::string> &invalid_peers);
96
97 /**
98 Simple multiplicative hash.
99
100 @param buf the data to create an hash from
101 @param length data length
102
103 @return calculated hash
104 */
105 static uint32_t mhash(unsigned char *buf, size_t length);
106
107 static int init_net();
108 static int deinit_net();
109
110 virtual ~Gcs_xcom_utils();
111 };
112
113 /**
114 @class gcs_xcom_control_proxy
115
116 This class is an abstraction layer between xcom and the actual
117 implementation. The purpose of this is to allow Gcs_xcom_control_interface
118 to be unit testable by creating mock classes on top of it.
119 */
120 class Gcs_xcom_proxy
121 {
122 public:
123 const static int connection_attempts= 10;
124
Gcs_xcom_proxy()125 explicit Gcs_xcom_proxy() {}
126
127 /**
128 The destructor.
129 */
~Gcs_xcom_proxy()130 virtual ~Gcs_xcom_proxy() {};
131
132
133 /**
134 This is an utility member function that is used to call into XCom for
135 creating list with node's addresses and their associated UUIDs. Note
136 that callers must provide the UUID.
137
138 @param n The number of elements in the list
139 @param names The names to be put on the list
140 @param uuids The UUIDs to be put on the list
141 @return a pointer to the list containing all the elements needed. The
142 caller is responsible to reclaim memory once he is done with this data
143 @c delete_node_address
144 */
145
146 virtual node_address *new_node_address_uuid(unsigned int n, char *names[], blob uuids[])= 0;
147
148
149 /**
150 This function is responsible to delete the list of nodes that had been
151 previously created by @c new_node_address.
152
153 @param n the length of the list
154 @param na the list to delete
155
156 @return false on success, true otherwise. In case of an error, memory may
157 not have been completely freed.
158 */
159
160 virtual void delete_node_address(unsigned int n, node_address *na)= 0;
161
162
163 /**
164 This member function is responsible to call into XCom consensus and add a
165 node to the group. The caller is responsible for ensuring that the session
166 has been opened before @c open_session and also that the node is not yet
167 in the configuration.
168
169 The callee must have opened an xcom connection before calling this
170 function. @c xcom_client_open_connection.
171
172 @param fd the file descriptor to the XCom connection established earlier
173 @param nl The node list containing the list of peers to add
174 @param group_id the identifier of the group to which the nodes should
175 be added
176
177 @return false on success, true otherwise. There could be errors later in
178 the process of adding a node. Since this is basically an asynchronous
179 function, one needs to wait for the actual view change to validate that we
180 were added to the configuration.
181 */
182
183 virtual int
184 xcom_client_add_node(connection_descriptor* fd, node_list *nl, uint32_t group_id)= 0;
185
186
187 /**
188 This member function is responsible for triggering the removal of a node
189 from the XCom configuration. This function is asynchronous, so you need to
190 wait for the view change to actually validate that the removal was
191 successful.
192
193 The caller is responsible for making sure that the server to be removed is
194 in the group.
195
196 This function MUST be called after opening the local xcom session
197 @c xcom_open_handlers.
198
199 @param nl The list of nodes to remove from the group
200 @param group_id The identifier of the group from which the nodes will
201 be removed
202 @param to_remove the node to remove
203 */
204
205 virtual int xcom_client_remove_node(node_list *nl, uint32_t group_id)= 0;
206
207 /**
208 This member function is responsible for triggering the removal of a node
209 from the XCom configuration. This function is asynchronous, so you need to
210 wait for the view change to actually validate that the removal was
211 successful.
212
213 The caller is responsible for making sure that the server to be removed is
214 in the group.
215
216 This function MUST be called after opening the local xcom session
217 @c xcom_open_handlers.
218
219 This method is to contact remote instances requesting for a node
220 to be removed. You can use the local version which is:
221 - int xcom_client_remove_node(node_list *nl, uint32_t group_id)
222
223 @param fd the file descriptor to the XCom connection established earlier
224 @param nl The list of nodes to remove from the group
225 @param group_id The identifier of the group from which the nodes will
226 be removed
227 @param to_remove the node to remove
228 */
229 virtual int xcom_client_remove_node(connection_descriptor* fd, node_list* nl,
230 uint32_t group_id)= 0;
231
232 /**
233 This member function is responsible for pushing data into consensus on
234 XCom. The caller is responsible to making sure that there is an open XCom
235 session @c xcom_open_handlers and also that the server is part of the XCom
236 configuration before sending data to it.
237
238 @param size the size of the payload
239 @param data the payload
240
241 @return 0 on success, not 0 otherwise
242 */
243
244 virtual int xcom_client_send_data(unsigned long long size, char *data)= 0;
245
246
247 /**
248 This member function initializes XCom. This function must be called before
249 anything else and from within the XCom thread. It will eventually call
250 the main loop inside XCom.
251
252 @param listen_port the port that the local XCom is to be listening on.
253 */
254
255 virtual int xcom_init(xcom_port listen_port)= 0;
256
257
258 /**
259 This member function finishes the XCom thread. This function must be
260 called when the XCOM thread was started but the node has not joined
261 a group.
262
263 @@param xcom_handlers_open indicates whether the handlers for the
264 xcom thread have already been opened.
265 */
266
267 virtual int xcom_exit(bool xcom_handlers_open)= 0;
268
269
270 /*
271 Return the operation mode as an integer from an operation mode provided
272 as a string. Note that the string must be provided in upper case letters
273 and the possible values are: "DISABLED", "PREFERRED", "REQUIRED",
274 "VERIFY_CA" or "VERIFY_IDENTITY".
275
276 If a different value is provide, INVALID_SSL_MODE (-1) is returned.
277 */
278
279 virtual int xcom_get_ssl_mode(const char* mode)= 0;
280
281
282 /*
283 Set the operation mode which might be the following:
284
285 . SSL_DISABLED (1): The SSL mode will be disabled and this is the default
286 value.
287
288 . SSL_PREFERRED (2): The SSL mode will be always disabled if this value is
289 provided and is only allowed to keep the solution compatibility with
290 MySQL server.
291
292 . SSL_REQUIRED (4): The SSL mode will be enabled but the verifications
293 described in the next modes are not performed.
294
295 . SSL_VERIFY_CA (4) - Verify the server TLS certificate against the configured
296 Certificate Authority (CA) certificates. The connection attempt fails if no
297 valid matching CA certificates are found.
298
299 . SSL_VERIFY_IDENTITY (5): Like VERIFY_CA, but additionally verify that the
300 server certificate matches the host to which the connection is attempted.
301
302 If a different value is provide, INVALID_SSL_MODE (-1) is returned.
303 */
304
305 virtual int xcom_set_ssl_mode(int mode)= 0;
306
307
308 /*
309 Initialize the SSL.
310 Return 0 if success 1 otherwise.
311 */
312
313 virtual int xcom_init_ssl()= 0;
314
315
316 /*
317 Destroy the SSL Configuration freeing allocated memory.
318 */
319
320 virtual void xcom_destroy_ssl()= 0;
321
322
323 /*
324 Return whether the SSL will be used to encrypt data or not.
325
326 Return 1 if it is enabled 0 otherwise.
327 */
328
329 virtual int xcom_use_ssl()= 0;
330
331
332 /*
333 Set the necessary SSL parameters before initialization.
334
335 server_key_file - Path of file that contains the server's X509 key in PEM
336 format.
337 server_cert_file - Path of file that contains the server's X509 certificate in
338 PEM format.
339 client_key_file - Path of file that contains the client's X509 key in PEM
340 format.
341 client_cert_file - Path of file that contains the client's X509 certificate in
342 PEM format.
343 ca_file - Path of file that contains list of trusted SSL CAs.
344 ca_path - Path of directory that contains trusted SSL CA certificates
345 in PEM format.
346 crl_file - Path of file that contains certificate revocation lists.
347 crl_path - Path of directory that contains certificate revocation list
348 files.
349 cipher - List of permitted ciphers to use for connection encryption.
350 tls_version - Protocols permitted for secure connections.
351
352 Note that only the server_key_file/server_cert_file and the client_key_file/
353 client_cert_file are required and the rest of the pointers can be NULL.
354 If the key is provided along with the certificate, either the key file or
355 the other can be ommited.
356
357 The caller can free the parameters after the SSL is started
358 if this is necessary.
359 */
360 virtual void xcom_set_ssl_parameters(const char *server_key_file,
361 const char *server_cert_file,
362 const char *client_key_file,
363 const char *client_cert_file,
364 const char *ca_file,
365 const char *ca_path,
366 const char *crl_file,
367 const char *crl_path,
368 const char *cipher,
369 const char *tls_version)= 0;
370
371
372 virtual site_def const *find_site_def(synode_no synode)= 0;
373
374 /**
375 This member function boots XCom.
376
377 @param nl List with a single member - the one that boots the group
378 @param group_id the Group identifier to which the member belongs to
379 @return false 0 on success, not 0 otherwise
380 */
381
382 virtual int xcom_client_boot(node_list *nl, uint32_t group_id)= 0;
383
384
385 /**
386 This member function opens a connection to an XCom instance.
387
388 @param addr The XCom instance address
389 @param port The XCom instance port
390 @return a valid file descriptor on success, -1 otherwise
391 */
392
393 virtual connection_descriptor* xcom_client_open_connection(std::string addr, xcom_port port)= 0;
394
395
396 /**
397 This member function closes the connection to an XCom instance.
398
399 @param fd The connection file descriptor
400 @return 0 on success, not 0 otherwise
401 */
402
403 virtual int xcom_client_close_connection(connection_descriptor* fd)= 0;
404
405
406 /**
407 This member function opens all the local connections to XCom needed before
408 one can push data into it.
409
410 Even though this is used to connect to a local XCom, it can be used to
411 connect to a standalone XCom.
412
413 @param addr The XCom address
414 @param port The XCom port
415
416 @return false on success, true otherwise. If there was an error, no
417 connection will have been created.
418 */
419
420 virtual bool xcom_open_handlers(std::string saddr, xcom_port port)= 0;
421
422
423 /**
424 This member function closes all the local connections to XCom that had been
425 previously opened by open_session.
426
427 @return false on success, true otherwise. If there was an error the state
428 of the connections is undefined.
429 */
430
431 virtual bool xcom_close_handlers()= 0;
432
433
434 /**
435 Acquires one of the handlers opened through @c xcom_open_handlers and locks
436 it.
437
438 The caller is responsible for releasing the handler once it is not needed
439 anymore.
440
441 This function is mostly used by the locally connecting functions such as
442 @c xcom_client_send_data, @c xcom_client_add_node,
443 @c xcom_client_remove_node, @c xcom_client_boot.
444
445 @return a valid handler to communicate with XCom
446 */
447
448 virtual int xcom_acquire_handler()= 0;
449
450
451 /**
452 Releases the handler and unlocks it.
453
454 @param fd The handler that was previously acquired
455 */
456
457 virtual void xcom_release_handler(int index)= 0;
458
459
460 /**
461 This member waits for XCom to be initialized.
462 */
463
464 virtual enum_gcs_error xcom_wait_ready()= 0;
465
466 /*
467 This member retrieves the value of XCom initialized
468 */
469 virtual bool xcom_is_ready()= 0;
470
471 /*
472 This member sets the value of XCom initialized
473 */
474 virtual void xcom_set_ready(bool value)= 0;
475
476 /*
477 This member signals that XCom has initialized.
478 */
479 virtual void xcom_signal_ready()= 0;
480
481 /**
482 @brief Call this method to wait for XCom communications to be initialized.
483
484 Call this method to wait for XCom communications to be initialized. It will
485 block until XCom communications are either OK or error out. The value of
486 the status (XCOM_COMMS_OK or XCOM_COMMS_ERROR) is written into the status
487 out parameters.
488
489 @param status[out] value of the XCom communication layer status.
490 It can be either XCOM_COMMS_OK or XCOM_COMMS_ERROR
491 */
492 virtual void xcom_wait_for_xcom_comms_status_change(int& status)= 0;
493
494 /*
495 This verifies if the communication status callback from XCom has been called
496 and if the internal cached status is different from XCOM_COMM_STATUS_UNDEFINED
497 */
498 virtual bool xcom_has_comms_status_changed()= 0;
499
500 /*
501 This sets the status value of communication status callback from XCom.
502 Its main purpose is to reset the internal cached status to XCOM_COMM_STATUS_UNDEFINED
503
504 @param status the new status value
505 */
506 virtual void xcom_set_comms_status(int status)= 0;
507
508 /*
509 This modifies the internal cached status to whatever value is delivered
510 by the XCom communication status callback. Then, it signals all threads
511 that might be waiting on xcom_wait_for_xcom_comms_status_change.
512
513 @param status the new status value
514 */
515 virtual void xcom_signal_comms_status_changed(int status)= 0;
516
517
518 /**
519 @brief Call this method to wait for XCom to exit.
520
521 Call this method to wait for XCom to exit. It will block until XCom has
522 exit or an error occurs.
523
524 @return GCS_OK if success, otherwise GCS_NOK.
525 */
526
527 virtual enum_gcs_error xcom_wait_exit()= 0;
528
529
530 /**
531 This verifies if XCom has finished or not.
532 */
533
534 virtual bool xcom_is_exit()= 0;
535
536
537 /**
538 This sets whether XCom has finished or not.
539 */
540
541 virtual void xcom_set_exit(bool value)= 0;
542
543
544 /**
545 Clean up variables used to notify states in the XCOM's state
546 machine.
547 */
548 virtual void xcom_set_cleanup()= 0;
549
550
551 /**
552 This modifies the internal cached status and signals all threads
553 that might be waiting on xcom_wait_exit.
554 */
555
556 virtual void xcom_signal_exit()= 0;
557
558
559 /**
560 This method forces XCom to inject a new configuration in the group,
561 even if it does not contain a majority of members.
562
563 @param nl The list of nodes that will belong to this new configuration
564 @param group_id The identifier of the group from which the nodes will
565 belong
566
567 @return
568 */
569 virtual int xcom_client_force_config(node_list *nl,
570 uint32_t group_id)= 0;
571
572 /**
573 This method forces XCom to inject a new configuration in the group,
574 even if it does not contain a majority of members.
575
576 @param fd the file descriptor to the XCom connection established earlier
577 @param nl The list of nodes that will belong to this new configuration
578 @param group_id The identifier of the group from which the nodes will
579 belong
580
581 @return
582 */
583 virtual int xcom_client_force_config(connection_descriptor *fd, node_list *nl,
584 uint32_t group_id)= 0;
585 };
586
587
588 /**
589 @class gcs_xcom_control_proxy_impl
590
591 Implementation of gcs_xcom_control_proxy to be used by whom
592 instantiates Gcs_xcom_control_interface to be used in a real
593 scenario.
594 */
595 class Gcs_xcom_proxy_impl : public Gcs_xcom_proxy
596 {
597 private:
598 class Xcom_handler
599 {
600 private:
601 My_xp_mutex_impl m_lock;
602 connection_descriptor* m_fd;
603 public:
604 explicit Xcom_handler();
605 virtual ~Xcom_handler();
606
get_fd()607 connection_descriptor* get_fd() { return m_fd; }
set_fd(connection_descriptor * fd)608 void set_fd(connection_descriptor* fd) { m_fd= fd; }
lock()609 void lock() { m_lock.lock(); }
unlock()610 void unlock() { m_lock.unlock(); }
611 private:
612 /*
613 Disabling the copy constructor and assignment operator.
614 */
615 Xcom_handler(Xcom_handler const&);
616 Xcom_handler& operator=(Xcom_handler const&);
617 };
618 public:
619 explicit Gcs_xcom_proxy_impl();
620 Gcs_xcom_proxy_impl(int wt);
621 virtual ~Gcs_xcom_proxy_impl();
622
623 node_address *new_node_address_uuid(unsigned int n, char *names[], blob uuids[]);
624 void delete_node_address(unsigned int n, node_address *na);
625 int xcom_client_add_node(connection_descriptor* fd, node_list *nl, uint32_t group_id);
626 int xcom_client_remove_node(connection_descriptor* fd, node_list* nl, uint32_t group_id);
627 int xcom_client_remove_node(node_list *nl, uint32_t group_id);
628 int xcom_client_boot(node_list *nl, uint32_t group_id);
629 connection_descriptor* xcom_client_open_connection(std::string, xcom_port port);
630 int xcom_client_close_connection(connection_descriptor* fd);
631 int xcom_client_send_data(unsigned long long size, char *data);
632 int xcom_init(xcom_port listen_port);
633 int xcom_exit(bool xcom_handlers_open);
634 int xcom_get_ssl_mode(const char* mode);
635 int xcom_set_ssl_mode(int mode);
636 int xcom_init_ssl();
637 void xcom_destroy_ssl();
638 int xcom_use_ssl();
639 void xcom_set_ssl_parameters(const char *server_key_file,
640 const char *server_cert_file,
641 const char *client_key_file,
642 const char *client_cert_file,
643 const char *ca_file, const char *ca_path,
644 const char *crl_file, const char *crl_path,
645 const char *cipher, const char *tls_version);
646 site_def const *find_site_def(synode_no synode);
647
648 bool xcom_open_handlers(std::string saddr, xcom_port port);
649 bool xcom_close_handlers();
650 int xcom_acquire_handler();
651 void xcom_release_handler(int index);
652 enum_gcs_error xcom_wait_ready();
653 bool xcom_is_ready();
654 void xcom_set_ready(bool value);
655 void xcom_signal_ready();
656
657 void xcom_wait_for_xcom_comms_status_change(int& status);
658 bool xcom_has_comms_status_changed();
659 void xcom_set_comms_status(int status);
660 void xcom_signal_comms_status_changed(int status);
661
662 enum_gcs_error xcom_wait_exit();
663 bool xcom_is_exit();
664 void xcom_set_exit(bool value);
665 void xcom_signal_exit();
666
667 void xcom_set_cleanup();
668
669 int xcom_client_force_config(node_list *nl, uint32_t group_id);
670 int xcom_client_force_config(connection_descriptor *fd, node_list *nl,
671 uint32_t group_id);
672
673 private:
674
675 /* A pointer to the next local XCom connection to use. */
676 int m_xcom_handlers_cursor;
677
678 /* This lock protects the list of local XCom connections. */
679 My_xp_mutex_impl m_lock_xcom_cursor;
680
681 /* The maximum number of local xcom connections. */
682 int m_xcom_handlers_size;
683
684 /*
685 Maximum waiting time used by timed_waits in xcom_wait_ready and
686 xcom_wait_for_xcom_comms_status_change.
687 */
688 int m_wait_time;
689
690 /* A list of local XCom connections. */
691 Xcom_handler **m_xcom_handlers;
692
693 // For synchronization between XCom and MySQL GCS infrastructure at startup.
694 My_xp_mutex_impl m_lock_xcom_ready;
695 My_xp_cond_impl m_cond_xcom_ready;
696 bool m_is_xcom_ready;
697
698 My_xp_mutex_impl m_lock_xcom_comms_status;
699 My_xp_cond_impl m_cond_xcom_comms_status;
700 int m_xcom_comms_status;
701
702 My_xp_mutex_impl m_lock_xcom_exit;
703 My_xp_cond_impl m_cond_xcom_exit;
704 bool m_is_xcom_exit;
705
706 My_xp_socket_util* m_socket_util;
707
708 // Stores SSL parameters
709 const char *m_server_key_file;
710 const char *m_server_cert_file;
711 const char *m_client_key_file;
712 const char *m_client_cert_file;
713 const char *m_ca_file;
714 const char *m_ca_path;
715 const char *m_crl_file;
716 const char *m_crl_path;
717 const char *m_cipher;
718 const char *m_tls_version;
719
720
721 /*
722 Disabling the copy constructor and assignment operator.
723 */
724 Gcs_xcom_proxy_impl(Gcs_xcom_proxy_impl const&);
725 Gcs_xcom_proxy_impl& operator=(Gcs_xcom_proxy_impl const&);
726 };
727
728 /**
729 A Gcs_xcom_interface needs to have an instance of this class
730 initialized before engaging XCom.
731 */
732 class Gcs_xcom_app_cfg
733 {
734 public:
Gcs_xcom_app_cfg()735 explicit Gcs_xcom_app_cfg() { }
736
~Gcs_xcom_app_cfg()737 virtual ~Gcs_xcom_app_cfg() { }
738
739 /**
740 Initializes the data structures to communicate with
741 XCom the application injected configuration options.
742 */
743 void init();
744
745 /**
746 Configures how many loops to spin before blocking on
747 the poll system call.
748 @param loops the number of spins.
749 */
750 void set_poll_spin_loops(unsigned int loops);
751
752 /**
753 Must be called when XCom is not engaged anymore.
754 */
755 void deinit();
756 };
757
758 typedef struct st_gcs_xcom_thread_startup_parameters
759 {
760 Gcs_xcom_proxy *proxy;
761 unsigned int port;
762 } Gcs_xcom_thread_startup_parameters;
763
764
765 /**
766 This class contains information on the configuration, i.e set of nodes
767 or simply site definition, used by XCOM to deliver a message or view.
768 */
769 class Gcs_xcom_nodes
770 {
771 public:
772 /**
773 Constructor that reads the site definition and whether a node
774 is considered dead or alive to build a list of addresses and
775 statuses.
776 */
777
778 explicit Gcs_xcom_nodes(const site_def *site, node_set &nodes);
779
780
781 /**
782 Empty constructor.
783 */
784
785 explicit Gcs_xcom_nodes();
786
787
788 /**
789 Return the index of the current node (i.e. member).
790 */
791
792 unsigned int get_node_no() const;
793
794
795 /**
796 Return a reference to the addresses' vector.
797 */
798
799 const std::vector<std::string> &get_addresses() const;
800
801 /**
802 Return a reference to the member uuids' vector.
803 */
804 const std::vector<Gcs_uuid> &get_uuids() const;
805
806 /**
807 Return a reference to the statuses' vector.
808 */
809
810 const std::vector<bool> &get_statuses() const;
811
812 /**
813 Return the GCS UUID associated to an address if there is one.
814 If the address is not found, NULL is returned.
815 */
816 const Gcs_uuid *get_uuid(const std::string &address) const;
817
818
819 /**
820 Return the number of nodes.
821 */
822
823 unsigned int get_size() const;
824
825
826 /**
827 Return with the configuration is valid or not.
828 */
is_valid()829 inline bool is_valid() const
830 {
831 /*
832 Unfortunately a node may get notifications even when its configuration
833 inside XCOM is not properly established and this may trigger view
834 changes and may lead to problems because the node is not really ready.
835
836 We detect this fact by checking the node identification is valid.
837 */
838 return m_node_no != VOID_NODE_NO;
839 }
840
841 private:
842 /*
843 Number of the current node which is used as an index to
844 the other data structures.
845 */
846 unsigned int m_node_no;
847
848 /*
849 List of addresses.
850 */
851 std::vector<std::string> m_addresses;
852
853 /*
854 List of uuids.
855 */
856 std::vector<Gcs_uuid> m_uuids;
857
858 /*
859 List that defines whether a node is alive or dead.
860 */
861 std::vector<bool> m_statuses;
862
863 /*
864 The size of the lists.
865 */
866 unsigned int m_size;
867 };
868
869 /*****************************************************
870 *****************************************************
871
872 Auxiliary checking functions.
873
874 *****************************************************
875 *****************************************************
876 */
877
878 /**
879 Checks whether the given string is a number or not
880 @param s the string to check.
881 @return true if it is a number, false otherwise.
882 */
is_number(const std::string & s)883 inline bool is_number(const std::string &s)
884 {
885 return s.find_first_not_of("0123456789") == std::string::npos;
886 }
887
888 /**
889 Parses the string "host:port" and checks if it is correct.
890
891 @param the server hostname and port in the form hostname:port.
892 @return true if it is a valid URL, false otherwise.
893 */
894 bool is_valid_hostname(const std::string &server_and_port);
895
896 /**
897 Does some transformations on the parameters. For instance, replaces
898 aliases with the correct ones
899 */
900 void
901 fix_parameters_syntax(Gcs_interface_parameters ¶ms);
902
903 /**
904 Checks that parameters are syntatically valid.
905
906 @param params The parameters to validate syntatically.
907 @returns false if there is a syntax error, true otherwise.
908 */
909 bool is_parameters_syntax_correct(const Gcs_interface_parameters ¶ms);
910
911 #endif /* GCS_XCOM_UTILS_INCLUDED */
912