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-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 <citrusleaf/cf_clock.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include <openssl/ssl.h>
25 
26 #include <aerospike/as_config.h>
27 
28 #if defined(__linux__) || defined(__APPLE__)
29 #include <unistd.h>
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
32 #include <sys/socket.h>
33 
34 // Windows send() and recv() parameter types are different.
35 #define as_socket_data_t void
36 #define as_socket_size_t size_t
37 #define as_close(fd) (close(fd))
38 #endif
39 
40 #if defined(__APPLE__)
41 #define SOL_TCP IPPROTO_TCP
42 #define MSG_NOSIGNAL 0
43 #endif
44 
45 #if defined(CF_WINDOWS)
46 #include <WinSock2.h>
47 #include <Ws2tcpip.h>
48 
49 #define as_socket_data_t char
50 #define as_socket_size_t int
51 #define as_close(fd) (closesocket(fd))
52 
53 #define MSG_DONTWAIT 0
54 #define MSG_NOSIGNAL 0
55 
56 #define SHUT_RDWR SD_BOTH
57 #endif // CF_WINDOWS
58 
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62 
63 /**
64  * This structure holds TLS context which can be shared (read-only)
65  * by all the connections to a specific cluster.
66  */
67 typedef struct as_tls_context_s {
68  SSL_CTX* ssl_ctx;
72 
73 /**
74  * This structure holds just an fd when we are not using TLS and additional
75  * OpenSSL context when we are using TLS.
76  */
77 typedef struct as_socket_s {
78  int fd;
79  int family;
81  const char* tls_name;
82  SSL* ssl;
83 } as_socket;
84 
85 /**
86  * @private
87  * Initialize an as_socket structure.
88  */
89 void
91 
92 /**
93  * @private
94  * Create non-blocking socket.
95  * Family should be AF_INET or AF_INET6.
96  */
97 int
98 as_socket_create_fd(int family);
99 
100 /**
101  * @private
102  * Create non-blocking socket.
103  * Family should be AF_INET or AF_INET6.
104  */
105 int
106 as_socket_create(as_socket* sock, int family, as_tls_context* ctx, const char* tls_name);
107 
108 /**
109  * @private
110  * Wrap existing fd in a socket.
111  * Family should be AF_INET or AF_INET6.
112  */
113 bool
114 as_socket_wrap(as_socket* sock, int family, int fd, as_tls_context* ctx, const char* tls_name);
115 
116 /**
117  * @private
118  * Connect to non-blocking socket.
119  */
120 bool
121 as_socket_start_connect(as_socket* sock, struct sockaddr* addr);
122 
123 /**
124  * @private
125  * Create non-blocking socket and connect.
126  */
127 as_status
128 as_socket_create_and_connect(as_socket* sock, as_error* err, struct sockaddr* addr, as_tls_context* ctx, const char* tls_name);
129 
130 /**
131  * @private
132  * Close and release resources associated with a as_socket.
133  */
134 void
136 
137 /**
138  * @private
139  * Peek for socket connection status using underlying fd.
140  * Needed to support libuv.
141  *
142  * @return 0 : socket is connected, but no data available.
143  * > 0 : byte size of data available.
144  * < 0 : socket is invalid.
145  */
146 int
147 as_socket_validate_fd(int fd);
148 
149 /**
150  * @private
151  * Peek for socket connection status.
152  *
153  * @return 0 : socket is connected, but no data available.
154  * > 0 : byte size of data available.
155  * < 0 : socket is invalid.
156  */
157 int
159 
160 #if defined(__linux__) || defined(__APPLE__)
161 
162 /**
163  * @private
164  * Calculate future deadline given timeout.
165  */
166 static inline uint64_t
167 as_socket_deadline(uint32_t timeout_ms)
168 {
169  return (timeout_ms && timeout_ms <= INT32_MAX)? cf_getms() + timeout_ms : 0;
170 }
171 
172 /**
173  * @private
174  * Write socket data without timeouts.
175  */
176 as_status
177 as_socket_write_forever(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len);
178 
179 /**
180  * @private
181  * Write socket data with future deadline in milliseconds.
182  * Do not adjust for zero deadline.
183  */
184 as_status
185 as_socket_write_limit(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint64_t deadline);
186 
187 /**
188  * @private
189  * Write socket data with future deadline in milliseconds.
190  * If deadline is zero, do not set deadline.
191  */
192 static inline as_status
193 as_socket_write_deadline(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint64_t deadline)
194 {
195  if (deadline) {
196  return as_socket_write_limit(err, sock, buf, buf_len, deadline);
197  }
198  else {
199  return as_socket_write_forever(err, sock, buf, buf_len);
200  }
201 }
202 
203 /**
204  * @private
205  * Write socket data with timeout in milliseconds.
206  * If timeout is zero or > MAXINT, do not set timeout.
207  */
208 static inline as_status
209 as_socket_write_timeout(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
210 {
211  if (timeout_ms && timeout_ms <= INT32_MAX) {
212  return as_socket_write_limit(err, sock, buf, buf_len, cf_getms() + timeout_ms);
213  }
214  else {
215  return as_socket_write_forever(err, sock, buf, buf_len);
216  }
217 }
218 
219 /**
220  * @private
221  * Read socket data without timeouts.
222  */
223 as_status
224 as_socket_read_forever(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len);
225 
226 /**
227  * @private
228  * Read socket data with future deadline in milliseconds.
229  * Do not adjust for zero deadline.
230  */
231 as_status
232 as_socket_read_limit(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint64_t deadline);
233 
234 /**
235  * @private
236  * Read socket data with future deadline in milliseconds.
237  * If deadline is zero, do not set deadline.
238  */
239 static inline as_status
240 as_socket_read_deadline(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint64_t deadline)
241 {
242  if (deadline) {
243  return as_socket_read_limit(err, sock, buf, buf_len, deadline);
244  }
245  else {
246  return as_socket_read_forever(err, sock, buf, buf_len);
247  }
248 }
249 
250 /**
251  * @private
252  * Read socket data with timeout in milliseconds.
253  * If timeout is zero or > MAXINT, do not set timeout.
254  */
255 static inline as_status
256 as_socket_read_timeout(as_error* err, as_socket* sock, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
257 {
258  if (timeout_ms && timeout_ms <= INT32_MAX) {
259  return as_socket_read_limit(err, sock, buf, buf_len, cf_getms() + timeout_ms);
260  }
261  else {
262  return as_socket_read_forever(err, sock, buf, buf_len);
263  }
264 }
265 
266 #endif
267 
268 #ifdef __cplusplus
269 } // end extern "C"
270 #endif
as_status
Definition: as_status.h:30
as_tls_context * ctx
Definition: as_socket.h:80
void * cert_blacklist
Definition: as_socket.h:69
int as_socket_validate(as_socket *sock)
int as_socket_validate_fd(int fd)
void as_socket_init(as_socket *sock)
int fd
Definition: as_socket.h:78
const char * tls_name
Definition: as_socket.h:81
SSL_CTX * ssl_ctx
Definition: as_socket.h:68
bool log_session_info
Definition: as_socket.h:70
void as_socket_close(as_socket *sock)
int as_socket_create_fd(int family)
bool as_socket_start_connect(as_socket *sock, struct sockaddr *addr)
int as_socket_create(as_socket *sock, int family, as_tls_context *ctx, const char *tls_name)
SSL * ssl
Definition: as_socket.h:82
bool as_socket_wrap(as_socket *sock, int family, int fd, as_tls_context *ctx, const char *tls_name)
int family
Definition: as_socket.h:79
as_status as_socket_create_and_connect(as_socket *sock, as_error *err, struct sockaddr *addr, as_tls_context *ctx, const char *tls_name)