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 #if defined(__linux__) || defined(__APPLE__)
25 #include <unistd.h>
26 #include <arpa/inet.h>
27 #include <netinet/in.h>
28 #include <sys/socket.h>
29 
30 // Windows send() and recv() parameter types are different.
31 #define as_socket_data_t void
32 #define as_socket_size_t size_t
33 #define as_close(fd) (close(fd))
34 #endif
35 
36 #if defined(__APPLE__)
37 #define SOL_TCP IPPROTO_TCP
38 #define MSG_NOSIGNAL 0
39 #endif
40 
41 #if defined(CF_WINDOWS)
42 #include <WinSock2.h>
43 #include <Ws2tcpip.h>
44 
45 #define as_socket_data_t char
46 #define as_socket_size_t int
47 #define as_close(fd) (closesocket(fd))
48 
49 #define MSG_DONTWAIT 0
50 #define MSG_NOSIGNAL 0
51 
52 #define SHUT_RDWR SD_BOTH
53 #endif // CF_WINDOWS
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 /**
60  * @private
61  * Create non-blocking socket.
62  */
63 int
65 
66 /**
67  * @private
68  * Connect to non-blocking socket.
69  */
71 as_socket_start_connect_nb(as_error* err, int fd, struct sockaddr_in *sa);
72 
73 /**
74  * @private
75  * Create non-blocking socket and connect.
76  */
78 as_socket_create_and_connect_nb(as_error* err, struct sockaddr_in *sa, int* fd);
79 
80 /**
81  * @private
82  * Peek for socket connection status.
83  *
84  * @return 0 : socket is connected, but no data available.
85  * > 0 : byte size of data available.
86  * < 0 : socket is invalid.
87  */
88 int
89 as_socket_validate(int fd);
90 
91 #if defined(__linux__) || defined(__APPLE__)
92 
93 /**
94  * @private
95  * Calculate future deadline given timeout.
96  */
97 static inline uint64_t
98 as_socket_deadline(uint32_t timeout_ms)
99 {
100  return (timeout_ms && timeout_ms <= INT32_MAX)? cf_getms() + timeout_ms : 0;
101 }
102 
103 /**
104  * @private
105  * Write socket data without timeouts.
106  */
107 as_status
108 as_socket_write_forever(as_error* err, int fd, uint8_t *buf, size_t buf_len);
109 
110 /**
111  * @private
112  * Write socket data with future deadline in milliseconds.
113  * Do not adjust for zero deadline.
114  */
115 as_status
116 as_socket_write_limit(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline);
117 
118 /**
119  * @private
120  * Write socket data with future deadline in milliseconds.
121  * If deadline is zero, do not set deadline.
122  */
123 static inline as_status
124 as_socket_write_deadline(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline)
125 {
126  if (deadline) {
127  return as_socket_write_limit(err, fd, buf, buf_len, deadline);
128  }
129  else {
130  return as_socket_write_forever(err, fd, buf, buf_len);
131  }
132 }
133 
134 /**
135  * @private
136  * Write socket data with timeout in milliseconds.
137  * If timeout is zero or > MAXINT, do not set timeout.
138  */
139 static inline as_status
140 as_socket_write_timeout(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
141 {
142  if (timeout_ms && timeout_ms <= INT32_MAX) {
143  return as_socket_write_limit(err, fd, buf, buf_len, cf_getms() + timeout_ms);
144  }
145  else {
146  return as_socket_write_forever(err, fd, buf, buf_len);
147  }
148 }
149 
150 /**
151  * @private
152  * Read socket data without timeouts.
153  */
154 as_status
155 as_socket_read_forever(as_error* err, int fd, uint8_t *buf, size_t buf_len);
156 
157 /**
158  * @private
159  * Read socket data with future deadline in milliseconds.
160  * Do not adjust for zero deadline.
161  */
162 as_status
163 as_socket_read_limit(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline);
164 
165 /**
166  * @private
167  * Read socket data with future deadline in milliseconds.
168  * If deadline is zero, do not set deadline.
169  */
170 static inline as_status
171 as_socket_read_deadline(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline)
172 {
173  if (deadline) {
174  return as_socket_read_limit(err, fd, buf, buf_len, deadline);
175  }
176  else {
177  return as_socket_read_forever(err, fd, buf, buf_len);
178  }
179 }
180 
181 /**
182  * @private
183  * Read socket data with timeout in milliseconds.
184  * If timeout is zero or > MAXINT, do not set timeout.
185  */
186 static inline as_status
187 as_socket_read_timeout(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
188 {
189  if (timeout_ms && timeout_ms <= INT32_MAX) {
190  return as_socket_read_limit(err, fd, buf, buf_len, cf_getms() + timeout_ms);
191  }
192  else {
193  return as_socket_read_forever(err, fd, buf, buf_len);
194  }
195 }
196 
197 /**
198  * @private
199  * Convert socket address to a string.
200  */
201 static inline void
202 as_socket_address_name(struct sockaddr_in* address, char* name)
203 {
204  inet_ntop(AF_INET, &(address->sin_addr), name, INET_ADDRSTRLEN);
205 }
206 
207 #endif
208 
209 #ifdef __cplusplus
210 } // end extern "C"
211 #endif