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. Close socket if not connected.
83  *
84  * @param fd Socket identifier.
85  * @param pipe If true, do not log message if socket contains data and do not close fd.
86  *
87  * @return if socket is connected.
88  */
89 bool
90 as_socket_validate(int fd, bool pipe);
91 
92 #if defined(__linux__) || defined(__APPLE__)
93 
94 /**
95  * @private
96  * Calculate future deadline given timeout.
97  */
98 static inline uint64_t
99 as_socket_deadline(uint32_t timeout_ms)
100 {
101  return (timeout_ms && timeout_ms <= INT32_MAX)? cf_getms() + timeout_ms : 0;
102 }
103 
104 /**
105  * @private
106  * Write socket data without timeouts.
107  */
108 as_status
109 as_socket_write_forever(as_error* err, int fd, uint8_t *buf, size_t buf_len);
110 
111 /**
112  * @private
113  * Write socket data with future deadline in milliseconds.
114  * Do not adjust for zero deadline.
115  */
116 as_status
117 as_socket_write_limit(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline);
118 
119 /**
120  * @private
121  * Write socket data with future deadline in milliseconds.
122  * If deadline is zero, do not set deadline.
123  */
124 static inline as_status
125 as_socket_write_deadline(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline)
126 {
127  if (deadline) {
128  return as_socket_write_limit(err, fd, buf, buf_len, deadline);
129  }
130  else {
131  return as_socket_write_forever(err, fd, buf, buf_len);
132  }
133 }
134 
135 /**
136  * @private
137  * Write socket data with timeout in milliseconds.
138  * If timeout is zero or > MAXINT, do not set timeout.
139  */
140 static inline as_status
141 as_socket_write_timeout(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
142 {
143  if (timeout_ms && timeout_ms <= INT32_MAX) {
144  return as_socket_write_limit(err, fd, buf, buf_len, cf_getms() + timeout_ms);
145  }
146  else {
147  return as_socket_write_forever(err, fd, buf, buf_len);
148  }
149 }
150 
151 /**
152  * @private
153  * Read socket data without timeouts.
154  */
155 as_status
156 as_socket_read_forever(as_error* err, int fd, uint8_t *buf, size_t buf_len);
157 
158 /**
159  * @private
160  * Read socket data with future deadline in milliseconds.
161  * Do not adjust for zero deadline.
162  */
163 as_status
164 as_socket_read_limit(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline);
165 
166 /**
167  * @private
168  * Read socket data with future deadline in milliseconds.
169  * If deadline is zero, do not set deadline.
170  */
171 static inline as_status
172 as_socket_read_deadline(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint64_t deadline)
173 {
174  if (deadline) {
175  return as_socket_read_limit(err, fd, buf, buf_len, deadline);
176  }
177  else {
178  return as_socket_read_forever(err, fd, buf, buf_len);
179  }
180 }
181 
182 /**
183  * @private
184  * Read socket data with timeout in milliseconds.
185  * If timeout is zero or > MAXINT, do not set timeout.
186  */
187 static inline as_status
188 as_socket_read_timeout(as_error* err, int fd, uint8_t *buf, size_t buf_len, uint32_t timeout_ms)
189 {
190  if (timeout_ms && timeout_ms <= INT32_MAX) {
191  return as_socket_read_limit(err, fd, buf, buf_len, cf_getms() + timeout_ms);
192  }
193  else {
194  return as_socket_read_forever(err, fd, buf, buf_len);
195  }
196 }
197 
198 /**
199  * @private
200  * Convert socket address to a string.
201  */
202 static inline void
203 as_socket_address_name(struct sockaddr_in* address, char* name)
204 {
205  inet_ntop(AF_INET, &(address->sin_addr), name, INET_ADDRSTRLEN);
206 }
207 
208 #endif
209 
210 #ifdef __cplusplus
211 } // end extern "C"
212 #endif
as_status
Definition: as_status.h:30
bool as_socket_validate(int fd, bool pipe)
as_status as_socket_start_connect_nb(as_error *err, int fd, struct sockaddr_in *sa)
as_status as_socket_create_and_connect_nb(as_error *err, struct sockaddr_in *sa, int *fd)
int as_socket_create_nb()