-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathccsocket.h
More file actions
261 lines (212 loc) · 9.28 KB
/
Copy pathccsocket.h
File metadata and controls
261 lines (212 loc) · 9.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#ifndef CCSOCKET_H
#define CCSOCKET_H
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdbool.h>
#if _WIN32
#define CCSOCKET_EXPORT __declspec(dllexport)
typedef char* cciovec_buf_t;
typedef uint32_t cciovec_len_t;
typedef intptr_t ccsocket_t;
#else
#define CCSOCKET_EXPORT __attribute__((visibility("default")))
#define INVALID_SOCKET (~0)
typedef void* cciovec_buf_t;
typedef size_t cciovec_len_t;
typedef int ccsocket_t;
#endif
typedef struct ccsocket_iovec
{
#if _WIN32
cciovec_len_t len;
cciovec_buf_t buf;
#else
cciovec_buf_t buf;
cciovec_len_t len;
#endif
} ccsocket_iovec_t;
/* init ccsocket_iovec_t */
#define ccsocket_init_iov(iov, count) memset((iov), 0x0, sizeof(ccsocket_iovec_t)*(count))
/* get/set ccsocket_iovec_t len */
#define ccsocket_get_iov_len(iov, idx) (iov)[idx].len
#define ccsocket_set_iov_len(iov, idx, slen) ccsocket_get_iov_len((iov), (idx)) = (cciovec_len_t)(slen)
/* get/set ccsocket_iovec_t len */
#define ccsocket_get_iov_buf(iov, idx) (iov)[idx].buf
#define ccsocket_set_iov_buf(iov, idx, sbuf) ccsocket_get_iov_buf((iov), (idx)) = (cciovec_buf_t)(sbuf)
#ifndef OPTIONAL
#define OPTIONAL /* When modifying a method parameter, it means that this parameter is optional and can be `NULL`. */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MAX_ADDRLEN
#define MAX_ADDRLEN 255
#endif
#ifndef MAX_ERRORLEN
#define MAX_ERRORLEN 255
#endif
typedef enum {
#define CC_NOFLAG CC_NOFLAG
CC_NOFLAG = 0,
#define CC_CLOEXEC CC_CLOEXEC
CC_CLOEXEC = 1,
#define CC_NONBLOCK CC_NONBLOCK
CC_NONBLOCK = 2,
} ccsocket_flags_t;
/* Used for `ccsocket_recv`/`ccsocket_send` and `cctls_recv`/`cctls_send`. */
typedef enum {
#define CC_OPCODE_ERROR CC_OPCODE_ERROR
CC_OPCODE_ERROR = -1,
#define CC_OPCODE_OK CC_OPCODE_OK
CC_OPCODE_OK = 0,
#define CC_OPCODE_WAIT CC_OPCODE_WAIT
CC_OPCODE_WAIT = 1,
#define CC_OPCODE_WANT_REVENT CC_OPCODE_WANT_REVENT
CC_OPCODE_WANT_REVENT = 2,
#define CC_OPCODE_WANT_WEVENT CC_OPCODE_WANT_WEVENT
CC_OPCODE_WANT_WEVENT = 3,
} ccsocket_stcode_t;
/* Used for ccsocket* */
typedef enum {
#define CC_FAMILY_INVALID CC_FAMILY_INVALID
CC_FAMILY_INVALID = -1,
#define CC_UNIX CC_UNIX
CC_UNIX = 0,
#define CC_INET4 CC_INET4
CC_INET4 = 1,
#define CC_INET6 CC_INET6
CC_INET6 = 2,
} ccsocket_family_t;
/* Used for ccsocket* */
typedef enum {
#define CC_PROTOCOL_INVALID CC_PROTOCOL_INVALID
CC_PROTOCOL_INVALID = -1,
#define CC_TCP CC_TCP
CC_TCP = 1,
#define CC_UDP CC_UDP
CC_UDP = 2,
#define CC_ICMP CC_ICMP
CC_ICMP = 3,
} ccsocket_protocol_t;
/* Used for ccsocket_connect* */
typedef enum {
#define CC_CONNERROR CC_CONNERROR
CC_CONNERROR = -1,
#define CC_CONNECTED CC_CONNECTED
CC_CONNECTED = 0,
#define CC_CONNECTING CC_CONNECTING
CC_CONNECTING = 1,
} ccsocket_conn_state_t;
/* Used for ccsocket_sendfile* */
typedef enum {
#define CC_SENDERROR CC_SENDERROR
CC_SENDERROR = -1,
#define CC_SENDALL CC_SENDALL
CC_SENDALL = 0,
#define CC_SENDWAIT CC_SENDWAIT
CC_SENDWAIT = 1,
#define CC_SENF_WANT_REVENT CC_SENF_WANT_REVENT
CC_SENF_WANT_REVENT = CC_OPCODE_WANT_REVENT,
#define CC_SENF_WANT_WEVENT CC_SENF_WANT_WEVENT
CC_SENF_WANT_WEVENT = CC_OPCODE_WANT_WEVENT,
} ccsocket_sendf_state_t;
/* close ccsocket */
CCSOCKET_EXPORT int ccsocket_close(ccsocket_t s);
/* pipe from ccsocketpair */
#define pipe(fds) ccsocket_pipe(fds)
CCSOCKET_EXPORT int ccsocket_pipe(ccsocket_t sv[2]);
/* create socketpair base `SOCK_STREAM` */
#define ccsocketpair(fds, flags) ccsocketpair1((fds), (ccsocket_flags_t)(flags))
/* `ccsocketpair` ABI (Try to avoid using it directly.) */
CCSOCKET_EXPORT bool ccsocketpair1(ccsocket_t sv[2], ccsocket_flags_t flags);
/* create `ccsocket` */
#define ccsocket(domain, protocol) ccsocket2((domain), (protocol), CC_NOFLAG)
/* create `ccsocket` with flags */
#define ccsocket1(domain, protocol, flags) ccsocket2((domain), (protocol), (ccsocket_flags_t)(flags))
/* `ccsocket/ccsocket1` ABI (Try to avoid using it directly.) */
CCSOCKET_EXPORT ccsocket_t ccsocket2(ccsocket_family_t domain, ccsocket_protocol_t proto, ccsocket_flags_t flags);
/* accept a client from listen `ccsocket`, return `(ccsocket_t)0` when non-block mode syscall want wait events. */
#define ccsocket_accept(s, flags) ccsocket_accept2((s), NULL, NULL, (ccsocket_flags_t)(flags))
/* accept client from listen `ccsocket` with client `address` and `port`, return `(ccsocket_t)0` when non-block mode syscall want wait events. */
#define ccsocket_accept1(s, paddr, pport, flags) ccsocket_accept2((s), (paddr), (pport), (ccsocket_flags_t)(flags))
/* `ccsocket_accept/ccsocket_accept1` ABI (Try to avoid using it directly.) */
CCSOCKET_EXPORT ccsocket_t ccsocket_accept2(ccsocket_t s, OPTIONAL char *addr, OPTIONAL uint16_t *port, ccsocket_flags_t flags);
/* listen a `ccsocket` (Only a listener) */
CCSOCKET_EXPORT bool ccsocket_listen(ccsocket_t s, const char *addr, uint16_t port);
/* listen a `ccsocket` with load balance in supported kernal.
* the following platforms support multi-process load balancing using `ccsocket`:
* DragonFly | FreeBSD , but listener must less than `255`.
* * Linux 3.9 : SO_REUSEPORT
* * DragonFlyBSD 3.6 : SO_REUSEPORT
* * FreeBSD 12 : SO_REUSEPORT_LB
* * Solaris 11.4 : SO_REUSEPORT
* * AIX 7.2.5.0 : SO_REUSEPORT
*/
CCSOCKET_EXPORT bool ccsocket_listen1(ccsocket_t s, const char *addr, uint16_t port);
/* connect to server using ccsocket. */
CCSOCKET_EXPORT bool ccsocket_connect(ccsocket_t s, const char *addr, uint16_t port);
/* check `ccsocket` connecting state. */
CCSOCKET_EXPORT ccsocket_conn_state_t ccsocket_is_connected(ccsocket_t s);
/* Read data sent by the peer from the `ccsocket`. */
CCSOCKET_EXPORT ccsocket_stcode_t ccsocket_recv(ccsocket_t s, char *buf, size_t bsize, OPTIONAL int *rsize);
/* Read iovec data sent by the peer from the `ccsocket`. */
CCSOCKET_EXPORT ccsocket_stcode_t ccsocket_recv1(ccsocket_t s, ccsocket_iovec_t *iov, int iovcnt, OPTIONAL int *rsize);
/* peek data from `ccsocket` without removing it from buffer. (platform must be supported) */
CCSOCKET_EXPORT ccsocket_stcode_t ccsocket_peek(ccsocket_t s, char* buf, size_t bsize, OPTIONAL int *rsize);
#define ccsocket_send(s, buf, bsize, wsizep) ccsocket_send1((s), (buf), (bsize), (wsizep), 0)
/* send buffer to peer `ccsocket` */
CCSOCKET_EXPORT ccsocket_stcode_t ccsocket_send1(ccsocket_t s, const void *buf, size_t bsize, OPTIONAL int *wsize, int flags);
#define ccsocket_sendv(s, iov, iovcnt, wsizep) ccsocket_sendv1((s), (iov), (iovcnt), (wsizep), 0)
/* send iovec buffer to peer `ccsocket` */
CCSOCKET_EXPORT ccsocket_stcode_t ccsocket_sendv1(ccsocket_t s, ccsocket_iovec_t *iov, int iovcnt, OPTIONAL int *wsize, int flags);
/* call sendfile using `ccsocket` with `zero-copy`(part). */
CCSOCKET_EXPORT ccsocket_sendf_state_t ccsocket_sendfile(ccsocket_t s, int fd);
/* ********** Below are some settings that can be used to change the behavior of `ccsocket` ********** */
/* get string error information from `ccsocket` */
CCSOCKET_EXPORT void ccsocket_get_error(ccsocket_t s, char buf[MAX_ERRORLEN]);
/* get peer address/port from `ccsocket` */
CCSOCKET_EXPORT bool ccsocket_get_peername(ccsocket_t s, char *addr, uint16_t *port);
/* get listen address/port from `ccsocket` */
CCSOCKET_EXPORT bool ccsocket_get_sockname(ccsocket_t s, char *addr, uint16_t *port);
/* get `Address Family` from `ccscket`, (e.g : check it's ipv4 or ipv6?) */
CCSOCKET_EXPORT ccsocket_family_t ccsocket_get_family(ccsocket_t s);
/* Check the ip protocol version from `addr` string.
* return once of `CC_INET4`, `CC_INET6`, `CC_UNIX`, `CC_FAMILY_INVALID`.
*/
CCSOCKET_EXPORT ccsocket_family_t ccsocket_get_version(const char *addr);
/* enable accept defer in listen tcp socket, becare unless you know it's behavior.
* Support Platform: `Linux` / `FreeBSD` / `Windows`(TODO).
*/
CCSOCKET_EXPORT bool ccsocket_enable_accept_defer(ccsocket_t s);
/* set the receive timeout (`timeout` in milliseconds). */
CCSOCKET_EXPORT bool ccsocket_set_rcvtimeout(ccsocket_t s, int timeout);
/* set the timeout period for sending (`timeout` in milliseconds). */
CCSOCKET_EXPORT bool ccsocket_set_sndtimeout(ccsocket_t s, int timeout);
/* set `ccsocket` cocnnection keep-alive(when peer in internet better). */
CCSOCKET_EXPORT bool ccsocket_set_keepalive(ccsocket_t s, bool on);
/* Used to enable/disable the `Nagle-algorithm`. */
CCSOCKET_EXPORT bool ccsocket_set_nodelay(ccsocket_t s, bool on);
/* Used to enable/disable the `reuse address`. */
CCSOCKET_EXPORT bool ccsocket_set_reuseaddr(ccsocket_t s, bool on);
/* Used to enable/disable the `reuse port`. */
CCSOCKET_EXPORT bool ccsocket_set_reuseport(ccsocket_t s, bool on);
/* Used to enable/disable the `ccsocket block/nonblock`. */
CCSOCKET_EXPORT bool ccsocket_set_nonblock(ccsocket_t s, bool on);
/* Used to enable/disable whether "sockets will be automatically inherited by sub-processes". */
CCSOCKET_EXPORT bool ccsocket_set_cloexec(ccsocket_t s, bool on);
/* addrinfo */
typedef struct ccaddrinfo
{
char address[65];
ccsocket_family_t af;
struct ccaddrinfo *next;
} ccaddrinfo_t;
/* getaddrinfo for domain */
CCSOCKET_EXPORT bool ccsocket_getaddrinfo(const char *domain, ccaddrinfo_t **addrlist);
/* free addrlist */
CCSOCKET_EXPORT void ccsocket_freeaddrinfo(ccaddrinfo_t *addrlist);
#ifdef __cplusplus
}
#endif
#endif /* CCSOCKET_H */