All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_node.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2016 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_error.h>
20 #include <aerospike/as_event.h>
21 #include <aerospike/as_socket.h>
22 #include <aerospike/as_queue.h>
23 #include <aerospike/as_vector.h>
24 #include <citrusleaf/cf_queue.h>
25 #include <netinet/in.h>
26 #include <sys/uio.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 // Concurrency kit needs to be under extern "C" when compiling C++.
33 #include <aerospike/ck/ck_pr.h>
34 
35 /******************************************************************************
36  * MACROS
37  *****************************************************************************/
38 
39 /**
40  * Maximum size (including NULL byte) of a hostname.
41  */
42 #define AS_HOSTNAME_SIZE 256
43 
44 /**
45  * Maximum size of node name
46  */
47 #define AS_NODE_NAME_SIZE 20
48 
49 // Leave this is in for backwards compatibility.
50 #define AS_NODE_NAME_MAX_SIZE AS_NODE_NAME_SIZE
51 
52 #define AS_FEATURES_GEO (1 << 0)
53 #define AS_FEATURES_DOUBLE (1 << 1)
54 #define AS_FEATURES_BATCH_INDEX (1 << 2)
55 #define AS_FEATURES_REPLICAS_ALL (1 << 3)
56 #define AS_FEATURES_PIPELINING (1 << 4)
57 #define AS_FEATURES_PEERS (1 << 5)
58 
59 #define AS_IP_ADDRESS_SIZE 64
60 #define AS_ADDRESS4_MAX 4
61 #define AS_ADDRESS6_MAX 8
62 
63 /******************************************************************************
64  * TYPES
65  *****************************************************************************/
66 
67 /**
68  * Socket address information.
69  */
70 typedef struct as_address_s {
71  /**
72  * Socket IP address.
73  */
74  struct sockaddr_storage addr;
75 
76  /**
77  * Socket IP address string representation including port.
78  */
79  char name[AS_IP_ADDRESS_SIZE];
80 
81 } as_address;
82 
83 /**
84  * @private
85  * Host address alias information.
86  */
87 typedef struct as_alias_s {
88  /**
89  * @private
90  * Hostname or IP address string representation.
91  */
92  char name[AS_HOSTNAME_SIZE];
93 
94  /**
95  * @private
96  * Socket IP port.
97  */
98  in_port_t port;
99 
100 } as_alias;
101 
102 struct as_cluster_s;
103 
104 /**
105  * Server node representation.
106  */
107 typedef struct as_node_s {
108  /**
109  * @private
110  * Reference count of node.
111  */
112  uint32_t ref_count;
113 
114  /**
115  * @private
116  * Server's generation count for partition management.
117  */
119 
120  /**
121  * @private
122  * TLS certificate name (needed for TLS only, NULL otherwise).
123  */
124  char* tls_name;
125 
126  /**
127  * The name of the node.
128  */
129  char name[AS_NODE_NAME_SIZE];
130 
131  /**
132  * @private
133  * Primary address index into addresses array.
134  */
135  uint32_t address_index;
136 
137  /**
138  * @private
139  * Number of IPv4 addresses.
140  */
141  uint32_t address4_size;
142 
143  /**
144  * @private
145  * Number of IPv6 addresses.
146  */
147  uint32_t address6_size;
148 
149  /**
150  * @private
151  * Array of IP addresses. Not thread-safe.
152  */
154 
155  /**
156  * @private
157  * Array of hostnames aliases. Not thread-safe.
158  */
159  as_vector /* <as_alias> */ aliases;
160 
161  struct as_cluster_s* cluster;
162 
163  /**
164  * @private
165  * Pool of current, cached sockets.
166  */
167  cf_queue* conn_q;
168 
169  /**
170  * @private
171  * Array of connection pools used in async commands. There is one pool per node/event loop.
172  * Only used by event loop threads. Not thread-safe.
173  */
175 
176  /**
177  * @private
178  * Pool of connections used in pipelined async commands. Also not thread-safe.
179  */
181 
182  /**
183  * @private
184  * Socket used exclusively for cluster tend thread info requests.
185  */
187 
188  /**
189  * @private
190  * Features supported by server. Stored in bitmap.
191  */
192  uint32_t features;
193 
194  /**
195  * @private
196  * Server's generation count for peers.
197  */
199 
200  /**
201  * @private
202  * Number of other nodes that consider this node a member of the cluster.
203  */
204  uint32_t conn_count;
205 
206  /**
207  * @private
208  * Number of other nodes that consider this node a member of the cluster.
209  */
210  uint32_t friends;
211 
212  /**
213  * @private
214  * Number of consecutive info request failures.
215  */
216  uint32_t failures;
217 
218  /**
219  * @private
220  * Shared memory node array index.
221  */
222  uint32_t index;
223 
224  /**
225  * @private
226  * Is node currently active.
227  */
228  uint8_t active;
229 
230  /**
231  * @private
232  * Did partition change in current cluster tend.
233  */
235 
236 } as_node;
237 
238 /**
239  * @private
240  * Node discovery information.
241  */
242 typedef struct as_node_info_s {
243  /**
244  * @private
245  * Node name.
246  */
247  char name[AS_NODE_NAME_SIZE];
248 
249  /**
250  * @private
251  * Features supported by server. Stored in bitmap.
252  */
253  uint32_t features;
254 
255  /**
256  * @private
257  * Validated socket.
258  */
260 
261 } as_node_info;
262 
263 /******************************************************************************
264  * FUNCTIONS
265  ******************************************************************************/
266 
267 /**
268  * @private
269  * Create new cluster node.
270  */
271 as_node*
273  struct as_cluster_s* cluster, const char* hostname, const char* tls_name,
274  in_port_t port, bool is_alias, struct sockaddr* addr, as_node_info* node_info
275  );
276 
277 /**
278  * @private
279  * Close all connections in pool and free resources.
280  */
281 void
282 as_node_destroy(as_node* node);
283 
284 /**
285  * @private
286  * Set node to inactive.
287  */
288 static inline void
290 {
291  // Make volatile write so changes are reflected in other threads.
292  ck_pr_store_8(&node->active, false);
293 }
294 
295 /**
296  * @private
297  * Reserve existing cluster node.
298  */
299 static inline void
301 {
302  //ck_pr_fence_acquire();
303  ck_pr_inc_32(&node->ref_count);
304 }
305 
306 /**
307  * @private
308  * Release existing cluster node.
309  */
310 static inline void
312 {
313  //ck_pr_fence_release();
314 
315  bool destroy;
316  ck_pr_dec_32_zero(&node->ref_count, &destroy);
317 
318  if (destroy) {
319  as_node_destroy(node);
320  }
321 }
322 
323 /**
324  * @private
325  * Add socket address to node addresses.
326  */
327 void
328 as_node_add_address(as_node* node, struct sockaddr* addr);
329 
330 /**
331  * @private
332  * Add hostname to node aliases.
333  */
334 void
335 as_node_add_alias(as_node* node, const char* hostname, in_port_t port);
336 
337 /**
338  * Get primary socket address.
339  */
340 static inline as_address*
342 {
343  return &node->addresses[node->address_index];
344 }
345 
346 /**
347  * Get socket address as a string.
348  */
349 static inline const char*
351 {
352  return node->addresses[node->address_index].name;
353 }
354 
355 /**
356  * @private
357  * Get a connection to the given node from pool and validate. Return 0 on success.
358  */
359 as_status
360 as_node_get_connection(as_error* err, as_node* node, uint64_t deadline_ms, as_socket* sock);
361 
362 /**
363  * @private
364  * Close a node's connection and do not put back into pool.
365  */
366 static inline void
368  as_socket_close(sock);
369  ck_pr_dec_32(&node->conn_count);
370 }
371 
372 /**
373  * @private
374  * Put connection back into pool.
375  */
376 static inline void
378 {
379  if (cf_queue_push(node->conn_q, sock) != CF_QUEUE_OK) {
380  as_node_close_connection(node, sock);
381  }
382 }
383 
384 /**
385  * @private
386  * Are hosts equal.
387  */
388 static inline bool
390 {
391  return strcmp(h1->name, h2->name) == 0 && h1->port == h2->port;
392 }
393 
394 #ifdef __cplusplus
395 } // end extern "C"
396 #endif