/*<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