All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_socket.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2021 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_address.h>
20 #include <aerospike/as_error.h>
21 #include <citrusleaf/cf_clock.h>
22 #include <pthread.h>
23 #include <stddef.h>
24 
25 #if !defined(_MSC_VER)
26 #include <unistd.h>
27 #include <arpa/inet.h>
28 #include <netinet/in.h>
29 #include <sys/socket.h>
30 #include <errno.h>
31 
32 #define as_socket_fd int
33 #define as_socket_data_t void
34 #define as_socket_size_t size_t
35 #define AS_CONNECTING EINPROGRESS
36 #define AS_WOULDBLOCK EWOULDBLOCK
37 #define as_close(_fd) close((_fd))
38 #define as_last_error() errno
39 
40 #if defined(__APPLE__)
41 #define SOL_TCP IPPROTO_TCP
42 #endif
43 
44 #else // _MSC_VER
45 #define as_socket_fd SOCKET
46 #define AS_CONNECTING WSAEWOULDBLOCK
47 #define AS_WOULDBLOCK WSAEWOULDBLOCK
48 #define SHUT_RDWR SD_BOTH
49 #define as_close(_fd) closesocket((_fd))
50 #define as_last_error() WSAGetLastError()
51 #endif
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 struct ssl_ctx_st;
58 struct evp_pkey_st;
59 
60 /**
61  * This structure holds TLS context which can be shared (read-only)
62  * by all the connections to a specific cluster.
63  */
64 typedef struct as_tls_context_s {
65  pthread_mutex_t lock;
66  struct ssl_ctx_st* ssl_ctx;
67  struct evp_pkey_st* pkey;
72 
73 struct as_conn_pool_s;
74 struct as_node_s;
75 
76 /**
77  * Socket fields for both regular and TLS sockets.
78  */
79 typedef struct as_socket_s {
80 #if !defined(_MSC_VER)
81  int fd;
82  int family;
83 #else
84  SOCKET fd;
85 #endif
86  union {
87  struct as_conn_pool_s* pool; // Used when sync socket is active.
88  uint64_t last_used; // Last used nano timestamp. Used when socket in pool.
89  };
91  const char* tls_name;
92  struct ssl_st* ssl;
93 } as_socket;
94 
95 /**
96  * @private
97  * Return true if TLS context exists and not TLS login only.
98  */
99 static inline bool
101 {
102  return (ctx && !ctx->for_login_only);
103 }
104 
105 /**
106  * @private
107  * Return TLS context only if exists and not for login only.
108  */
109 static inline as_tls_context*
111 {
112  return (ctx && !ctx->for_login_only) ? ctx : NULL;
113 }
114 
115 /**
116  * @private
117  * Initialize an as_socket structure.
118  */
119 void
121 
122 /**
123  * @private
124  * Create non-blocking socket. Family should be AF_INET or AF_INET6.
125  * Return zero on success.
126  */
127 int
128 as_socket_create_fd(int family, as_socket_fd* fdp);
129 
130 /**
131  * @private
132  * Create non-blocking socket.
133  * Family should be AF_INET or AF_INET6.
134  * Return zero on success.
135  */
136 int
137 as_socket_create(as_socket* sock, int family, as_tls_context* ctx, const char* tls_name);
138 
139 /**
140  * @private
141  * Wrap existing fd in a socket.
142  * Family should be AF_INET or AF_INET6.
143  */
144 bool
145 as_socket_wrap(as_socket* sock, int family, as_socket_fd fd, as_tls_context* ctx, const char* tls_name);
146 
147 /**
148  * @private
149  * Connect to non-blocking socket.
150  */
151 static inline bool
152 as_socket_connect_fd(as_socket_fd fd, struct sockaddr* addr, socklen_t size)
153 {
154  return connect(fd, addr, size) == 0 || as_last_error() == AS_CONNECTING;
155 }
156 
157 /**
158  * @private
159  * Connect to non-blocking socket and perform sync TLS connect if TLS enabled.
160  */
161 bool
162 as_socket_start_connect(as_socket* sock, struct sockaddr* addr, uint64_t deadline_ms);
163 
164 /**
165  * @private
166  * Create non-blocking socket and connect.
167  */
168 as_status
169 as_socket_create_and_connect(as_socket* sock, as_error* err, struct sockaddr* addr, as_tls_context* ctx, const char* tls_name, uint64_t deadline_ms);
170 
171 /**
172  * @private
173  * Close and release resources associated with a as_socket.
174  */
175 void
177 
178 /**
179  * @private
180  * Create error message for socket error.
181  */
182 as_status
183 as_socket_error(as_socket_fd fd, struct as_node_s* node, as_error* err, as_status status, const char* msg, int code);
184 
185 /**
186  * @private
187  * Append address to error message.
188  */
189 void
190 as_socket_error_append(as_error* err, struct sockaddr* addr);
191 
192 /**
193  * @private
194  * Is socket idle within limit for transactions.
195  */
196 static inline bool
197 as_socket_current_tran(uint64_t last_used, uint64_t max_socket_idle_ns)
198 {
199  return max_socket_idle_ns == 0 || (cf_getns() - last_used) <= max_socket_idle_ns;
200 }
201 
202 /**
203  * @private
204  * Is socket idle within limit for trimming idle sockets in cluster tend thread.
205  */
206 static inline bool
207 as_socket_current_trim(uint64_t last_used, uint64_t max_socket_idle_ns)
208 {
209  return (cf_getns() - last_used) <= max_socket_idle_ns;
210 }
211 
212 /**
213  * @private
214  * Peek for socket connection status using underlying fd.
215  * Needed to support libuv.
216  *
217  * @return 0 : socket is connected, but no data available.
218  * > 0 : byte size of data available.
219  * < 0 : socket is invalid.
220  */
221 int
223 
224 /**
225  * @private
226  * Calculate future deadline given timeout.
227  */
228 static inline uint64_t
229 as_socket_deadline(uint32_t timeout_ms)
230 {
231  return (timeout_ms && timeout_ms <= INT32_MAX)? cf_getms() + timeout_ms : 0;
232 }
233 
234 /**
235  * @private
236  * Write socket data with future deadline in milliseconds.
237  * If deadline is zero, do not set deadline.
238  */
239 as_status
241  as_error* err, as_socket* sock, struct as_node_s* node, uint8_t *buf, size_t buf_len,
242  uint32_t socket_timeout, uint64_t deadline
243  );
244 
245 /**
246  * @private
247  * Read socket data with future deadline in milliseconds.
248  * If deadline is zero, do not set deadline.
249  */
250 as_status
252  as_error* err, as_socket* sock, struct as_node_s* node, uint8_t *buf, size_t buf_len,
253  uint32_t socket_timeout, uint64_t deadline
254  );
255 
256 #ifdef __cplusplus
257 } // end extern "C"
258 #endif
as_status
Definition: as_status.h:30
#define as_socket_fd
Definition: as_socket.h:32
#define AS_CONNECTING
Definition: as_socket.h:35
bool for_login_only
Definition: as_socket.h:70
struct evp_pkey_st * pkey
Definition: as_socket.h:67
as_tls_context * ctx
Definition: as_socket.h:90
bool as_socket_wrap(as_socket *sock, int family, as_socket_fd fd, as_tls_context *ctx, const char *tls_name)
struct ssl_st * ssl
Definition: as_socket.h:92
void as_socket_error_append(as_error *err, struct sockaddr *addr)
static bool as_socket_connect_fd(as_socket_fd fd, struct sockaddr *addr, socklen_t size)
Definition: as_socket.h:152
#define as_last_error()
Definition: as_socket.h:38
void * cert_blacklist
Definition: as_socket.h:68
as_status as_socket_create_and_connect(as_socket *sock, as_error *err, struct sockaddr *addr, as_tls_context *ctx, const char *tls_name, uint64_t deadline_ms)
bool as_socket_start_connect(as_socket *sock, struct sockaddr *addr, uint64_t deadline_ms)
int as_socket_validate_fd(as_socket_fd fd)
as_status as_socket_write_deadline(as_error *err, as_socket *sock, struct as_node_s *node, uint8_t *buf, size_t buf_len, uint32_t socket_timeout, uint64_t deadline)
static as_tls_context * as_socket_get_tls_context(as_tls_context *ctx)
Definition: as_socket.h:110
void as_socket_init(as_socket *sock)
int as_socket_create_fd(int family, as_socket_fd *fdp)
int fd
Definition: as_socket.h:81
struct as_conn_pool_s * pool
Definition: as_socket.h:87
const char * tls_name
Definition: as_socket.h:91
uint64_t last_used
Definition: as_socket.h:88
static bool as_socket_use_tls(as_tls_context *ctx)
Definition: as_socket.h:100
pthread_mutex_t lock
Definition: as_socket.h:65
struct ssl_ctx_st * ssl_ctx
Definition: as_socket.h:66
bool log_session_info
Definition: as_socket.h:69
as_status as_socket_read_deadline(as_error *err, as_socket *sock, struct as_node_s *node, uint8_t *buf, size_t buf_len, uint32_t socket_timeout, uint64_t deadline)
void as_socket_close(as_socket *sock)
as_status as_socket_error(as_socket_fd fd, struct as_node_s *node, as_error *err, as_status status, const char *msg, int code)
static bool as_socket_current_trim(uint64_t last_used, uint64_t max_socket_idle_ns)
Definition: as_socket.h:207
int as_socket_create(as_socket *sock, int family, as_tls_context *ctx, const char *tls_name)
static bool as_socket_current_tran(uint64_t last_used, uint64_t max_socket_idle_ns)
Definition: as_socket.h:197
int family
Definition: as_socket.h:82
static uint64_t as_socket_deadline(uint32_t timeout_ms)
Definition: as_socket.h:229