1 /*
2  *   Copyright (c) 2014 - 2019 Oleh Kulykov <info@resident.name>
3  *
4  *   Permission is hereby granted, free of charge, to any person obtaining a copy
5  *   of this software and associated documentation files (the "Software"), to deal
6  *   in the Software without restriction, including without limitation the rights
7  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  *   copies of the Software, and to permit persons to whom the Software is
9  *   furnished to do so, subject to the following conditions:
10  *
11  *   The above copyright notice and this permission notice shall be included in
12  *   all copies or substantial portions of the Software.
13  *
14  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  *   THE SOFTWARE.
21  */
22 
23 
24 #ifndef __RWS_SOCKET_H__
25 #define __RWS_SOCKET_H__ 1
26 
27 #include "rws_common.h"
28 
29 #if defined(RWS_OS_WINDOWS)
30 #include <winsock2.h>
31 #include <ws2tcpip.h>
32 #else
33 #include <sys/socket.h>
34 #include <netdb.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 #endif
38 
39 #include <assert.h>
40 #include <errno.h>
41 
42 #include "rws_error.h"
43 #include "rws_thread.h"
44 #include "rws_frame.h"
45 #include "rws_list.h"
46 
47 #ifdef WEBSOCKET_SSL_ENABLE
48 #include "mbedtls/net.h"
49 #include "mbedtls/ssl.h"
50 #include "mbedtls/certs.h"
51 #include "mbedtls/entropy.h"
52 #include "mbedtls/ctr_drbg.h"
53 #include "mbedtls/debug.h"
54 #endif
55 
56 typedef int rws_socket_t;
57 #define RWS_INVALID_SOCKET -1
58 #define RWS_SOCK_CLOSE(sock) close(sock)
59 
60 static const char * k_rws_socket_min_http_ver = "1.1";
61 static const char * k_rws_socket_sec_websocket_accept = "sec-websocket-accept";
62 static const char * k_rws_socket_sec_websocket_accept_alt = "Sec-WebSocket-Accept";
63 
64 #ifdef WEBSOCKET_SSL_ENABLE
65 typedef struct _rws_ssl_struct
66 {
67     mbedtls_ssl_context ssl_ctx;        /* mbedtls ssl context */
68     mbedtls_net_context net_ctx;        /* Fill in socket id */
69     mbedtls_ssl_config ssl_conf;        /* SSL configuration */
70     // mbedtls_entropy_context entropy;
71     // mbedtls_ctr_drbg_context ctr_drbg;
72     mbedtls_x509_crt_profile profile;
73     mbedtls_x509_crt cacert;
74     mbedtls_x509_crt clicert;
75     mbedtls_pk_context pkey;
76 } _rws_ssl;
77 #endif
78 
79 struct rws_socket_struct {
80 	int port;
81 	rws_socket_t socket;
82 	char * scheme;
83 	char * host;
84 	char * path;
85 
86     char * sec_ws_protocol;// "Sec-WebSocket-Protocol" field
87 	char * sec_ws_accept;  // "Sec-WebSocket-Accept" field from handshake
88 
89 	rws_thread work_thread;
90 
91 	int command;
92 
93 	unsigned int next_message_id;
94 
95 	rws_bool is_connected; // sock connected + handshake done
96 
97 	void * user_object;
98 	rws_on_socket on_connected;
99 	rws_on_socket on_disconnected;
100 	rws_on_socket_recvd_text on_recvd_text;
101 	rws_on_socket_recvd_bin on_recvd_bin;
102 	rws_on_socket_recvd_pong on_recvd_pong;
103     rws_on_socket_send_ping  on_send_ping;
104 
105 	void * received;
106 	size_t received_size; // size of 'received' memory
107 	size_t received_len; // length of actualy readed message
108 
109 	_rws_list * send_frames;
110 	_rws_list * recvd_frames;
111 
112 	rws_error error;
113 
114 	rws_mutex work_mutex;
115 	rws_mutex send_mutex;
116 	rws_sem exit_sem;
117 
118 #ifdef WEBSOCKET_SSL_ENABLE
119     const char *server_cert;        /**< Server certification. */
120     const char *client_cert;        /**< Client certification. */
121     const char *client_pk;          /**< Client private key. */
122     int server_cert_len;            /**< Server certification lenght, server_cert buffer size. */
123     int client_cert_len;            /**< Client certification lenght, client_cert buffer size. */
124     int client_pk_len;              /**< Client private key lenght, client_pk buffer size. */
125     _rws_ssl *ssl;                  /**< Ssl content. */
126 #endif
127 
128 	char *recv_buffer;
129 	int recv_buffer_size;
130 };
131 
132 rws_bool rws_socket_process_handshake_responce(rws_socket s);
133 
134 // receive raw data from socket
135 rws_bool rws_socket_recv(rws_socket s);
136 
137 // send raw data to socket
138 rws_bool rws_socket_send(rws_socket s, const void * data, const size_t data_size);
139 
140 _rws_frame * rws_socket_last_unfin_recvd_frame_by_opcode(rws_socket s, const rws_opcode opcode);
141 
142 void rws_socket_process_bin_or_text_frame(rws_socket s, _rws_frame * frame);
143 
144 void rws_socket_process_ping_frame(rws_socket s, _rws_frame * frame);
145 
146 void rws_socket_process_pong_frame(rws_socket s, _rws_frame * frame);
147 
148 void rws_socket_process_conn_close_frame(rws_socket s, _rws_frame * frame);
149 
150 void rws_socket_process_received_frame(rws_socket s, _rws_frame * frame);
151 
152 void rws_socket_idle_recv(rws_socket s);
153 
154 void rws_socket_idle_send(rws_socket s);
155 
156 void rws_socket_wait_handshake_responce(rws_socket s);
157 
158 unsigned int rws_socket_get_next_message_id(rws_socket s);
159 
160 rws_bool rws_socket_send_ping_priv(rws_socket s);
161 
162 void rws_socket_send_disconnect(rws_socket s);
163 
164 void rws_socket_send_handshake(rws_socket s);
165 
166 struct addrinfo * rws_socket_connect_getaddr_info(rws_socket s);
167 
168 void rws_socket_connect_to_host(rws_socket s);
169 
170 rws_bool rws_socket_create_start_work_thread(rws_socket s);
171 
172 void rws_socket_close(rws_socket s);
173 
174 void rws_socket_resize_received(rws_socket s, const size_t size);
175 
176 void rws_socket_append_recvd_frames(rws_socket s, _rws_frame * frame);
177 
178 void rws_socket_append_send_frames(rws_socket s, _rws_frame * frame);
179 
180 rws_bool rws_socket_send_text_priv(rws_socket s, const char * text);
181 
182 rws_bool rws_socket_send_bin_priv(rws_socket s, const char *bin, size_t len, rws_binary bin_type);
183 
184 rws_bool rws_socket_send_bin_continue_priv(rws_socket s, const char *bin, size_t len);
185 
186 rws_bool rws_socket_send_bin_finish_priv(rws_socket s, const char *bin, size_t len);
187 
188 void rws_socket_inform_recvd_frames(rws_socket s);
189 
190 void rws_socket_set_option(rws_socket_t s, int option, int value);
191 
192 void rws_socket_delete_all_frames_in_list(_rws_list * list_with_frames);
193 
194 void rws_socket_check_write_error(rws_socket s, int error_num);
195 
196 void rws_socket_delete(rws_socket s);
197 
198 #ifdef WEBSOCKET_SSL_ENABLE
199 int rws_ssl_conn(rws_socket s);
200 int rws_ssl_close(rws_socket s);
201 #endif
202 
203 #define COMMAND_IDLE -1
204 #define COMMAND_NONE 0
205 #define COMMAND_CONNECT_TO_HOST 1
206 #define COMMAND_SEND_HANDSHAKE 2
207 #define COMMAND_WAIT_HANDSHAKE_RESPONCE 3
208 #define COMMAND_INFORM_CONNECTED 4
209 #define COMMAND_INFORM_DISCONNECTED 5
210 #define COMMAND_DISCONNECT 6
211 
212 #define COMMAND_END 9999
213 
214 
215 
216 #endif
217