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