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
262
263
264
265
266
267
268
269
270
271
272
273
|
/*<copyright>
* <year>1999-2008</year>
* <holder>Ericsson AB, All Rights Reserved</holder>
*</copyright>
*<legalnotice>
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of the Original Code is Ericsson AB.
*</legalnotice>
*/
/*
* Purpose: Implementation of Secure Socket Layer (SSL).
*
*/
#ifndef ESOCK_H
#define ESOCK_H
#ifdef __WIN32__
#include "esock_winsock.h"
#endif
#include <stdio.h>
#ifdef __WIN32__
#define INVALID_FD INVALID_SOCKET
#define sock_read(fd, buf, len) recv((fd), (buf), (len), 0)
#define sock_write(fd, buf, len) send((fd), (buf), (len), 0)
#define sock_close(fd) closesocket(fd)
#define sock_errno() WSAGetLastError()
#define sock_set_errno(err) WSASetLastError(err)
#define ERRNO_NONE 0
#define ERRNO_BLOCK WSAEWOULDBLOCK
#define ERRNO_CONNREFUSED WSAECONNREFUSED
#define ERRNO_PROGRESS WSAEINPROGRESS
#define ERRNO_PROTONOSUPPORT WSAEPROTONOSUPPORT
#define ERRNO_INVAL WSAEINVAL
#define ERRNO_ADDRNOTAVAIL WSAEADDRNOTAVAIL
#define ERRNO_NOTSOCK WSAENOTSOCK
#define ERRNO_OPNOTSUPP WSAEOPNOTSUPP
#define ERRNO_MFILE WSAEMFILE
#define SET_BLOCKING(fd) do { \
unsigned long zeroval = 0; \
ioctlsocket((fd), FIONBIO, &zeroval); \
} while (0)
#define SET_NONBLOCKING(fd) do { \
unsigned long oneval = 1; \
ioctlsocket((fd), FIONBIO, &oneval); \
} while (0)
#else
#define INVALID_FD (-1)
#define sock_read(fd, buf, len) read((fd), (buf), (len))
#define sock_write(fd, buf, len) write((fd), (buf), (len))
#define sock_close(fd) close(fd)
#define sock_errno() errno
#define sock_set_errno(err) do {errno = (err);} while(0)
#define ERRNO_NONE 0
#define ERRNO_BLOCK EAGAIN
#define ERRNO_CONNREFUSED ECONNREFUSED
#define ERRNO_PROGRESS EINPROGRESS
#define ERRNO_PROTONOSUPPORT EPROTONOSUPPORT
#define ERRNO_INVAL EINVAL
#define ERRNO_ADDRNOTAVAIL EADDRNOTAVAIL
#define ERRNO_NOTSOCK ENOTSOCK
#define ERRNO_OPNOTSUPP EOPNOTSUPP
#define ERRNO_MFILE EMFILE
#define SET_BLOCKING(fd) fcntl((fd), F_SETFL, \
fcntl((fd), F_GETFL, 0) & ~O_NONBLOCK)
#define SET_NONBLOCKING(fd) fcntl((fd), F_SETFL, \
fcntl((fd), F_GETFL, 0) | O_NONBLOCK)
#endif
#define GET_INT8(s) ((s)[0])
#define GET_INT16(s) (((s)[0] << 8) | (s)[1])
#define GET_INT32(s) (((s)[0] << 24) | ((s)[1] << 16) | \
((s)[2] << 8) | (s)[3])
#define PUT_INT8(x, s) do { (s)[0] = x; } while(0)
#define PUT_INT16(x, s) do { (s)[0] = ((x) >> 8) & 0xff; \
(s)[1] = ((x) & 0xff); } while(0)
#define PUT_INT32(x, s) do { (s)[0] = ((x) >> 24) & 0xff; \
(s)[1] = ((x) >> 16) & 0xff; \
(s)[2] = ((x) >> 8) & 0xff; \
(s)[3] = (x) & 0xff; } while(0)
/* type for Connections */
#define ESOCK_STATE_NONE 0
#define ESOCK_ACTIVE_LISTENING 1
#define ESOCK_PASSIVE_LISTENING 2
#define ESOCK_CONNECTED 3
#define ESOCK_WAIT_CONNECT 4
#define ESOCK_SSL_CONNECT 5
#define ESOCK_SSL_ACCEPT 6
#define ESOCK_TRANSPORT_ACCEPT 7
#define ESOCK_JOINED 8
#define ESOCK_SSL_SHUTDOWN 9
#define ESOCK_DEFUNCT 10
#ifdef __WIN32__
typedef SOCKET FD;
#else
typedef int FD;
#endif
/* For the shutdown(fd, how) call */
#ifdef __WIN32__
#define SHUTDOWN_READ SD_RECEIVE
#define SHUTDOWN_WRITE SD_SEND
#define SHUTDOWN_ALL SD_BOTH
#else
#define SHUTDOWN_READ 0
#define SHUTDOWN_WRITE 1
#define SHUTDOWN_ALL 2
#endif
#define ORIG_LISTEN 0
#define ORIG_ACCEPT 1
#define ORIG_CONNECT 2
typedef struct {
int size; /* Total size of buf */
unsigned char *buf;
int len; /* Current number of bytes in buf */
int offset; /* Bytes already written */
} WriteQueue;
typedef struct _proxy Proxy;
typedef struct Connection {
FD fd;
FD listen_fd; /* Needed for async listen error */
unsigned char state;
int acceptors; /* Count acceptors for listen socket */
Proxy *proxy;
void *opaque; /* Any suitable ssl structure */
int ssl_want; /* read/write flags */
int eof; /* end of file (read) */
int bp; /* broken pipe (write) */
int clean; /* Clean SSL shutdown initiated */
int close; /* Close if set */
int origin; /* listen, accept or connect */
int encrypted; /* 1 = SSL encrypted, 0 = normal, unencrypted tcp */
char *flags; /* ssl parameters */
FILE *logfp; /* connection log file (not used) */
WriteQueue wq;
struct Connection* next;
const char* errstr; /* only used to report errors from ssl_accept_init in SSL_ACCEPT */
} Connection;
struct _proxy {
FD fd;
int peer_port;
int eof; /* end of file (read) */
int bp; /* broken pipe (write) */
Connection *conn;
WriteQueue wq;
Proxy *next;
};
/* Commands, replies, and error responses */
#define ESOCK_CONNECT_CMD 1
#define ESOCK_CONNECT_WAIT_REP 2
#define ESOCK_CONNECT_REP 3
#define ESOCK_CONNECT_ERR 4
#define ESOCK_TERMINATE_CMD 5
#define ESOCK_CLOSE_CMD 6
#define ESOCK_LISTEN_CMD 7
#define ESOCK_LISTEN_REP 8
#define ESOCK_LISTEN_ERR 9
#define ESOCK_TRANSPORT_ACCEPT_CMD 10
#define ESOCK_NOACCEPT_CMD 11
#define ESOCK_TRANSPORT_ACCEPT_REP 12
#define ESOCK_TRANSPORT_ACCEPT_ERR 13
#define ESOCK_FROMNET_CLOSE_REP 14
#define ESOCK_CONNECT_SYNC_ERR 15
#define ESOCK_LISTEN_SYNC_ERR 16
#define ESOCK_PROXY_PORT_REP 23
#define ESOCK_PROXY_JOIN_CMD 24
#define ESOCK_PROXY_JOIN_REP 25
#define ESOCK_PROXY_JOIN_ERR 26
#define ESOCK_SET_SOCKOPT_CMD 27
#define ESOCK_IOCTL_OK 28
#define ESOCK_IOCTL_ERR 29
#define ESOCK_GETPEERNAME_CMD 30
#define ESOCK_GETPEERNAME_REP 31
#define ESOCK_GETPEERNAME_ERR 32
#define ESOCK_GETSOCKNAME_CMD 33
#define ESOCK_GETSOCKNAME_REP 34
#define ESOCK_GETSOCKNAME_ERR 35
#define ESOCK_GETPEERCERT_CMD 36
#define ESOCK_GETPEERCERT_REP 37
#define ESOCK_GETPEERCERT_ERR 38
#define ESOCK_GETVERSION_CMD 39
#define ESOCK_GETVERSION_REP 40
#define ESOCK_SET_SEED_CMD 41
#define ESOCK_GETCONNINFO_CMD 42
#define ESOCK_GETCONNINFO_REP 43
#define ESOCK_GETCONNINFO_ERR 44
#define ESOCK_SSL_ACCEPT_CMD 45
#define ESOCK_SSL_ACCEPT_REP 46
#define ESOCK_SSL_ACCEPT_ERR 47
#define ESOCK_DUMP_STATE_CMD 48
#define ESOCK_SET_DEBUG_CMD 49
#define ESOCK_SET_DEBUGMSG_CMD 50
/* Option codes for ESOCK_SET_SOCKOPT_CMD */
#define ESOCK_SET_TCP_NODELAY 1
/* SSL want to read or write */
#define ESOCK_SSL_WANT_READ 1
#define ESOCK_SSL_WANT_WRITE 2
/* Protocol version according to ssl_server */
#define ESOCK_SSLv2 1
#define ESOCK_SSLv3 2
#define ESOCK_TLSv1 4
#endif
|