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 #include "librws.h"
25 #include "rws_socket.h"
26 #include "rws_memory.h"
27 #include "rws_string.h"
28
29 #define READ_TIMEOUT_MS 5000
30 #define WRITE_TIMEOUT_MS 5000
31 #define RWS_CONNECT_RETRY_DELAY 200
32 #define RWS_CONNECT_ATTEMPS 2
33
34 #define WSAEWOULDBLOCK EAGAIN
35 #define WSAEINPROGRESS EINPROGRESS
36
37 #ifndef MAX_THRESH_VAL
38 #define MAX_THRESH_VAL 204800 /* common TTS play size */
39 #endif
40
rws_socket_get_next_message_id(rws_socket s)41 unsigned int rws_socket_get_next_message_id(rws_socket s) {
42 const unsigned int mess_id = ++s->next_message_id;
43 if (mess_id > 9999999) {
44 s->next_message_id = 0;
45 }
46 return mess_id;
47 }
48
rws_socket_send_ping_priv(rws_socket s)49 rws_bool rws_socket_send_ping_priv(rws_socket s) {
50 char buff[16];
51 size_t len = 0;
52 _rws_frame * frame = rws_frame_create();
53
54 if (frame == NULL)
55 return rws_false;
56
57 len = rws_sprintf(buff, 16, "%u", rws_socket_get_next_message_id(s));
58
59 frame->is_masked = rws_true;
60 frame->opcode = rws_opcode_ping;
61 rws_frame_fill_with_send_data(frame, buff, len, rws_true);
62 rws_socket_append_send_frames(s, frame);
63
64 return rws_true;
65 }
66
rws_socket_inform_recvd_frames(rws_socket s)67 void rws_socket_inform_recvd_frames(rws_socket s) {
68 rws_bool is_all_finished = rws_true;
69 _rws_frame * frame = NULL;
70 _rws_node * cur = s->recvd_frames;
71 while (cur) {
72 frame = (_rws_frame *)cur->value.object;
73 if (frame) {
74 //if (frame->is_finished) {
75 switch (frame->opcode) {
76 case rws_opcode_continuation:
77 // continue send finish
78 if (s->on_recvd_bin) {
79 s->on_recvd_bin(s, frame->data, (unsigned int)frame->data_size, frame->is_finished);
80 }
81 break;
82 case rws_opcode_text_frame:
83 if (s->on_recvd_text) {
84 s->on_recvd_text(s, (const char *)frame->data, (unsigned int)frame->data_size, frame->is_finished);
85 }
86 break;
87 case rws_opcode_binary_frame:
88 if (s->on_recvd_bin) {
89 s->on_recvd_bin(s, frame->data, (unsigned int)frame->data_size, frame->is_finished);
90 }
91 break;
92 case rws_opcode_pong:
93 if (s->on_recvd_pong) {
94 s->on_recvd_pong(s);
95 }
96 break;
97 default: break;
98 }
99 rws_frame_delete(frame);
100 cur->value.object = NULL;
101 /*} else {
102 is_all_finished = rws_false;
103 }*/
104 }
105 cur = cur->next;
106 }
107 if (is_all_finished) {
108 rws_list_delete_clean(&s->recvd_frames);
109 }
110 }
111
rws_socket_read_handshake_responce_value(const char * str,char ** value)112 void rws_socket_read_handshake_responce_value(const char * str, char ** value) {
113 const char * s = NULL;
114 size_t len = 0;
115
116 while (*str == ':' || *str == ' ') {
117 str++;
118 }
119 s = str;
120 while (*s != '\r' && *s != '\n') {
121 s++;
122 len++;
123 }
124 if (len > 0) {
125 *value = rws_string_copy_len(str, len);
126 }
127 }
128
rws_socket_process_handshake_responce(rws_socket s)129 rws_bool rws_socket_process_handshake_responce(rws_socket s) {
130 const char * str = (const char *)s->received;
131 const char * sub = NULL;
132 const char * accept_str = NULL;
133
134 float http_ver = -1;
135 int http_code = -1;
136
137 rws_error_delete_clean(&s->error);
138 sub = strstr(str, "HTTP/");
139 if (!sub) {
140 return rws_false;
141 }
142
143 //sub += 5;
144 sub += 9;
145 // ATTENTION: some platform may not support float
146 //if (rws_sscanf(sub, "%f %i", &http_ver, &http_code) != 2) {
147 if (rws_sscanf(sub, "%i", &http_code) != 1) {
148 http_ver = -1;
149 http_code = -1;
150 }
151
152 sub = strstr(str, k_rws_socket_sec_websocket_accept); // "Sec-WebSocket-Accept"
153 if (sub) {
154 accept_str = k_rws_socket_sec_websocket_accept;
155 } else {
156 sub = strstr(str, k_rws_socket_sec_websocket_accept_alt);
157 if (sub) {
158 accept_str = k_rws_socket_sec_websocket_accept_alt;
159 }
160 }
161
162 if (sub) {
163 sub += strlen(accept_str);
164 rws_socket_read_handshake_responce_value(sub, &s->sec_ws_accept);
165 }
166
167 if (http_code != 101 || !s->sec_ws_accept) {
168 s->error = rws_error_new_code_descr(rws_error_code_parse_handshake,
169 (http_code != 101) ? "HTPP code not found or non 101" : "Accept key not found");
170 return rws_false;
171 }
172 return rws_true;
173 }
174
175 // need close socket on error
rws_socket_send(rws_socket s,const void * data,const size_t data_size)176 rws_bool rws_socket_send(rws_socket s, const void * data, const size_t data_size) {
177 int sended = -1, error_number = -1;
178 uint32_t writtenLen = 0;
179 rws_error_delete_clean(&s->error);
180
181 while (writtenLen < data_size) {
182 #ifdef WEBSOCKET_SSL_ENABLE
183 if (s->scheme && strcmp(s->scheme, "wss") == 0) {
184 if (s->ssl)
185 sended = mbedtls_ssl_write(&(s->ssl->ssl_ctx), (const unsigned char *)(data + writtenLen), (int)(data_size - writtenLen));
186 else {
187 ERR("%s %d ssl invlalid ctx", __func__, __LINE__);
188 sended = -1;
189 break;
190 }
191 }
192 else
193 #endif
194 sended = (int)send(s->socket, (data + writtenLen), (int)(data_size - writtenLen), 0);
195
196 if (sended > 0) {
197 writtenLen += sended;
198 } else {
199 error_number = errno;
200 break;
201 }
202 }
203
204 if (sended > 0) {
205 if (sended < data_size) {
206 WRN("%s %d sended %d but want %d", __func__, __LINE__, sended, data_size);
207 }
208
209 return rws_true;
210 }
211
212 rws_socket_check_write_error(s, error_number);
213 if (s->error) {
214 ERR("rws_socket_send return %d\n", error_number);
215 rws_socket_close(s);
216 }
217
218 return rws_false;
219 }
220
rws_socket_recv(rws_socket s)221 rws_bool rws_socket_recv(rws_socket s) {
222 int is_reading = 1, error_number = -1, len = -1;
223 char * received = NULL;
224 size_t total_len = 0;
225 char *buffer = NULL;
226 int buffer_size = 0;
227 int ssl_status = 0;
228
229 buffer = s->recv_buffer;
230 buffer_size = s->recv_buffer_size;
231 if (NULL == buffer || buffer_size <= 0) {
232 return false;
233 }
234 memset(buffer, 0, buffer_size);
235 rws_error_delete_clean(&s->error);
236
237 while (is_reading) {
238 #ifdef WEBSOCKET_SSL_ENABLE
239 if(s->scheme && strcmp(s->scheme, "wss") == 0) {
240 if (s->ssl) {
241 len = mbedtls_ssl_read(&(s->ssl->ssl_ctx), (unsigned char *)buffer, buffer_size);
242 } else {
243 ERR("%s %d ssl invlalid ctx", __func__, __LINE__);
244 return false;
245 }
246 }
247 else
248 #endif
249 len = (int)recv(s->socket, buffer, buffer_size, 0);
250
251 error_number = errno;
252 if (len > 0) {
253 total_len += len;
254 if (s->received_size - s->received_len < len) {
255 #ifdef _AMLOGIC_
256 if (s->received_size + len > MAX_THRESH_VAL) {
257 WRN("Message len exceed MAX_THRESH_VAL, drop it!");
258 s->received_len = 0;
259 continue;
260 }
261 #endif
262
263 rws_socket_resize_received(s, s->received_size + len);
264 }
265 received = (char *)s->received;
266 if (s->received_len) {
267 received += s->received_len;
268 }
269 memcpy(received, buffer, len);
270 s->received_len += len;
271 } else if (len == 0) {
272 is_reading = 0;
273 } else {
274 is_reading = 0;
275 #ifdef WEBSOCKET_SSL_ENABLE
276 if(s->scheme && strcmp(s->scheme, "wss") == 0) {
277 if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == len) {
278 ERR("peer close -0x%04x", -len);
279 // net_status = -2; /* connection is closed */
280 } else if ((MBEDTLS_ERR_SSL_TIMEOUT == len)
281 || (MBEDTLS_ERR_SSL_CONN_EOF == len)
282 || (MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED == len)
283 || (MBEDTLS_ERR_SSL_NON_FATAL == len)) {
284 /* read already complete */
285 /* if call mbedtls_ssl_read again, it will return 0 (means EOF) */
286 ssl_status = 1;
287 } else {
288 /* Connection error */
289 ERR("recv -0x%04x", -len);
290 }
291 }
292 #endif
293 }
294
295 }
296
297 //if (error_number < 0) return rws_true;
298 if (error_number != WSAEWOULDBLOCK && error_number != WSAEINPROGRESS
299 && ssl_status != 1) {
300 ERR("in close websocket %d\n", error_number);
301
302 s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, "Failed read/write socket");
303 rws_socket_close(s);
304 return rws_false;
305 }
306
307 return rws_true;
308 }
309
rws_socket_last_unfin_recvd_frame_by_opcode(rws_socket s,const rws_opcode opcode)310 _rws_frame * rws_socket_last_unfin_recvd_frame_by_opcode(rws_socket s, const rws_opcode opcode) {
311 _rws_frame * last = NULL;
312 _rws_frame * frame = NULL;
313 _rws_node * cur = s->recvd_frames;
314 while (cur) {
315 frame = (_rws_frame *)cur->value.object;
316 if (frame) {
317 // [FIN=0,opcode !=0 ],[FIN=0,opcode ==0 ],....[FIN=1,opcode ==0 ]
318 if (!frame->is_finished /*&& frame->opcode == opcode*/) {
319 last = frame;
320 }
321 }
322 cur = cur->next;
323 }
324 return last;
325 }
326
rws_socket_process_bin_or_text_frame(rws_socket s,_rws_frame * frame)327 void rws_socket_process_bin_or_text_frame(rws_socket s, _rws_frame * frame) {
328 _rws_frame * last_unfin = rws_socket_last_unfin_recvd_frame_by_opcode(s, frame->opcode);
329 if (last_unfin) {
330 rws_frame_combine_datas(last_unfin, frame);
331 last_unfin->is_finished = frame->is_finished;
332 rws_frame_delete(frame);
333 } else if (frame->data && frame->data_size) {
334 rws_socket_append_recvd_frames(s, frame);
335 } else if (frame->data_size == 0 && frame->is_finished) {
336 rws_socket_append_recvd_frames(s, frame);
337 } else {
338 rws_frame_delete(frame);
339 }
340 }
341
rws_socket_process_pong_frame(rws_socket s,_rws_frame * frame)342 void rws_socket_process_pong_frame(rws_socket s, _rws_frame * frame) {
343 rws_socket_append_recvd_frames(s, frame);
344 }
345
rws_socket_process_ping_frame(rws_socket s,_rws_frame * frame)346 void rws_socket_process_ping_frame(rws_socket s, _rws_frame * frame) {
347 _rws_frame * pong_frame = rws_frame_create();
348 pong_frame->opcode = rws_opcode_pong;
349 pong_frame->is_masked = rws_true;
350 rws_frame_fill_with_send_data(pong_frame, frame->data, frame->data_size, rws_true);
351 rws_frame_delete(frame);
352 rws_socket_append_send_frames(s, pong_frame);
353 }
354
rws_socket_process_conn_close_frame(rws_socket s,_rws_frame * frame)355 void rws_socket_process_conn_close_frame(rws_socket s, _rws_frame * frame) {
356 s->command = COMMAND_INFORM_DISCONNECTED;
357 s->error = rws_error_new_code_descr(rws_error_code_connection_closed, "Connection was closed by endpoint");
358 //rws_socket_close(s);
359 rws_frame_delete(frame);
360 }
361
rws_socket_process_received_frame(rws_socket s,_rws_frame * frame)362 void rws_socket_process_received_frame(rws_socket s, _rws_frame * frame) {
363 DBG("%s: frame->opcode:%d", __FUNCTION__, frame->opcode);
364 switch (frame->opcode) {
365 case rws_opcode_ping: rws_socket_process_ping_frame(s, frame); break;
366 case rws_opcode_pong:
367 DBG("%s: rws_opcode_pong\n", __FUNCTION__);
368 if (s->on_recvd_pong) s->on_recvd_pong(s);
369 rws_frame_delete(frame);
370 break;
371 case rws_opcode_text_frame:
372 case rws_opcode_binary_frame:
373 case rws_opcode_continuation:
374 rws_socket_process_bin_or_text_frame(s, frame);
375 break;
376 case rws_opcode_connection_close: rws_socket_process_conn_close_frame(s, frame); break;
377 default:
378 // unprocessed => delete
379 rws_frame_delete(frame);
380 break;
381 }
382 }
383
rws_socket_idle_recv(rws_socket s)384 void rws_socket_idle_recv(rws_socket s) {
385 _rws_frame * frame = NULL;
386
387 if (!rws_socket_recv(s)) {
388 // sock already closed
389 if (s->error) {
390 s->command = COMMAND_INFORM_DISCONNECTED;
391 }
392 return;
393 }
394
395 const size_t nframe_size = rws_check_recv_frame_size(s->received, s->received_len);
396 if (nframe_size) {
397 frame = rws_frame_create_with_recv_data(s->received, nframe_size);
398 if (frame) {
399 rws_socket_process_received_frame(s, frame);
400 }
401
402 if (nframe_size == s->received_len) {
403 s->received_len = 0;
404 } else if (s->received_len > nframe_size) {
405 const size_t nLeftLen = s->received_len - nframe_size;
406 memmove((char*)s->received, (char*)s->received + nframe_size, nLeftLen);
407 s->received_len = nLeftLen;
408 }
409 }
410 }
411
rws_socket_idle_send(rws_socket s)412 void rws_socket_idle_send(rws_socket s) {
413 _rws_node * cur = NULL;
414 rws_bool sending = rws_true;
415 _rws_frame * frame = NULL;
416
417 rws_mutex_lock(s->send_mutex);
418 cur = s->send_frames;
419 if (cur) {
420 while (cur && s->is_connected && sending) {
421 frame = (_rws_frame *)cur->value.object;
422 cur->value.object = NULL;
423 if (frame) {
424 sending = rws_socket_send(s, frame->data, frame->data_size);
425
426 if (sending) {
427 if (rws_opcode_ping == frame->opcode &&
428 s->on_send_ping) {
429 s->on_send_ping(s);
430 }
431 }
432 }
433 rws_frame_delete(frame);
434 cur = cur->next;
435 }
436 rws_socket_delete_all_frames_in_list(s->send_frames);
437 rws_list_delete_clean(&s->send_frames);
438 if (s->error) {
439 s->command = COMMAND_INFORM_DISCONNECTED;
440 }
441 }
442 rws_mutex_unlock(s->send_mutex);
443 }
444
rws_socket_wait_handshake_responce(rws_socket s)445 void rws_socket_wait_handshake_responce(rws_socket s) {
446 if (!rws_socket_recv(s)) {
447 // sock already closed
448 if (s->error) {
449 s->command = COMMAND_INFORM_DISCONNECTED;
450 }
451 return;
452 }
453
454 if (s->received_len == 0) {
455 return;
456 }
457
458 if (rws_socket_process_handshake_responce(s)) {
459 s->received_len = 0;
460 s->is_connected = rws_true;
461 s->command = COMMAND_INFORM_CONNECTED;
462 } else {
463 rws_socket_close(s);
464 s->command = COMMAND_INFORM_DISCONNECTED;
465 }
466 }
467
rws_socket_send_disconnect(rws_socket s)468 void rws_socket_send_disconnect(rws_socket s) {
469 char buff[16];
470 size_t len = 0;
471 _rws_frame * frame = NULL;
472
473 if (s->socket == RWS_INVALID_SOCKET)
474 return;
475
476 frame = rws_frame_create();
477
478 len = rws_sprintf(buff, 16, "%u", rws_socket_get_next_message_id(s));
479
480 frame->is_masked = rws_true;
481 frame->opcode = rws_opcode_connection_close;
482 rws_frame_fill_with_send_data(frame, buff, len, rws_true);
483 rws_socket_send(s, frame->data, frame->data_size);
484 rws_frame_delete(frame);
485 s->command = COMMAND_END;
486 rws_thread_sleep(RWS_CONNECT_RETRY_DELAY); // little bit wait after send message
487 }
488
rws_socket_send_handshake(rws_socket s)489 void rws_socket_send_handshake(rws_socket s) {
490 char buff[512];
491 char * ptr = buff;
492 size_t writed = 0;
493 char * protocol = (s->sec_ws_protocol ? s->sec_ws_protocol : "chat, superchat");
494 writed = rws_sprintf(ptr, 512, "GET %s HTTP/%s\r\n", s->path, k_rws_socket_min_http_ver);
495
496 if (s->port == 80) {
497 writed += rws_sprintf(ptr + writed, 512 - writed, "Host: %s\r\n", s->host);
498 } else {
499 writed += rws_sprintf(ptr + writed, 512 - writed, "Host: %s:%i\r\n", s->host, s->port);
500 }
501
502 writed += rws_sprintf(ptr + writed, 512 - writed,
503 "Upgrade: websocket\r\n"
504 "Connection: Upgrade\r\n"
505 "Origin: %s://%s\r\n",
506 s->scheme, s->host);
507
508 writed += rws_sprintf(ptr + writed, 512 - writed,
509 "Sec-WebSocket-Key: %s\r\n"
510 "Sec-WebSocket-Protocol: %s\r\n"
511 "Sec-WebSocket-Version: 13\r\n"
512 "\r\n",
513 "dGhlIHNhbXBsZSBub25jZQ==", protocol);
514
515 if (rws_socket_send(s, buff, writed)) {
516 s->command = COMMAND_WAIT_HANDSHAKE_RESPONCE;
517 } else {
518 if (s->error) {
519 s->error->code = rws_error_code_send_handshake;
520 } else {
521 s->error = rws_error_new_code_descr(rws_error_code_send_handshake, "Send handshake");
522 }
523 rws_socket_close(s);
524 s->command = COMMAND_INFORM_DISCONNECTED;
525 }
526 }
527
rws_socket_connect_getaddr_info(rws_socket s)528 struct addrinfo * rws_socket_connect_getaddr_info(rws_socket s) {
529 struct addrinfo hints;
530 char portstr[16];
531 struct addrinfo * result = NULL;
532 int ret = 0, retry_number = 0, last_ret = 0;
533
534 rws_error_delete_clean(&s->error);
535
536 rws_sprintf(portstr, 16, "%i", s->port);
537 while (++retry_number < RWS_CONNECT_ATTEMPS) {
538 result = NULL;
539 memset(&hints, 0, sizeof(hints));
540 hints.ai_family = AF_UNSPEC;
541 hints.ai_socktype = SOCK_STREAM;
542
543 ret = getaddrinfo(s->host, portstr, &hints, &result);
544 if (ret == 0 && result) {
545 return result;
546 }
547
548 WRN("websoc getaddrinfo failed! try times: %d!", retry_number);
549
550 if (ret != 0) {
551 last_ret = ret;
552 }
553
554 if (result) {
555 freeaddrinfo(result);
556 }
557
558 rws_thread_sleep(RWS_CONNECT_RETRY_DELAY);
559 }
560
561 // s->error = rws_error_new_code_descr(rws_error_code_connect_to_host,
562 // (last_ret > 0) ? gai_strerror(last_ret) : "Failed connect to host");
563 s->error = rws_error_new_code_descr(rws_error_code_connect_to_host,
564 "Failed connect to host");
565 s->command = COMMAND_INFORM_DISCONNECTED;
566
567 ERR("websoc connect_getaddr_info failed!");
568 return NULL;
569 }
570
rws_socket_connect_to_host(rws_socket s)571 void rws_socket_connect_to_host(rws_socket s) {
572 struct addrinfo * result = NULL;
573 struct addrinfo * p = NULL;
574 rws_socket_t sock = RWS_INVALID_SOCKET;
575 int retry_number = 0;
576
577 result = rws_socket_connect_getaddr_info(s);
578 if (!result) {
579 return;
580 }
581
582 while ((++retry_number < RWS_CONNECT_ATTEMPS) && (sock == RWS_INVALID_SOCKET)) {
583 for (p = result; p != NULL; p = p->ai_next) {
584 sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
585 if (sock != RWS_INVALID_SOCKET) {
586 rws_socket_set_option(sock, SO_ERROR, 1); // When an error occurs on a socket, set error variable so_error and notify process
587 rws_socket_set_option(sock, SO_KEEPALIVE, 1); // Periodically test if connection is alive
588
589 if (connect(sock, p->ai_addr, p->ai_addrlen) == 0) {
590 s->received_len = 0;
591 s->socket = sock;
592 fcntl(s->socket, F_SETFL, O_NONBLOCK);
593 break;
594 }
595 RWS_SOCK_CLOSE(sock);
596 sock = RWS_INVALID_SOCKET;
597 WRN("websoc connect failed! try times: %d!", retry_number);
598 }
599 }
600
601 if (sock == RWS_INVALID_SOCKET) {
602 rws_thread_sleep(RWS_CONNECT_RETRY_DELAY);
603 }
604 }
605
606 freeaddrinfo(result);
607
608 if (s->socket == RWS_INVALID_SOCKET) {
609 ERR("websoc rws_socket_connect_to_host failed!");
610 s->error = rws_error_new_code_descr(rws_error_code_connect_to_host, "Failed connect to host");
611 s->command = COMMAND_INFORM_DISCONNECTED;
612 } else {
613 s->command = COMMAND_SEND_HANDSHAKE;
614 }
615 }
616
rws_socket_work_th_func(void * user_object)617 static void rws_socket_work_th_func(void * user_object) {
618 rws_socket s = (rws_socket)user_object;
619
620 while (s->command < COMMAND_END) {
621 rws_mutex_lock(s->work_mutex);
622 switch (s->command) {
623 case COMMAND_CONNECT_TO_HOST:
624 {
625 #ifdef WEBSOCKET_SSL_ENABLE
626 if(s->scheme && strcmp(s->scheme, "wss") == 0) {
627 rws_ssl_conn(s);
628 DBG("after rws_ssl_conn %d\n", s->command);
629 break;
630 }
631 else
632 #endif /* WEBSOCKET_SSL_ENABLE */
633 {
634 rws_socket_connect_to_host(s); break;
635 }
636 }
637 case COMMAND_SEND_HANDSHAKE: rws_socket_send_handshake(s); break;
638 case COMMAND_WAIT_HANDSHAKE_RESPONCE: rws_socket_wait_handshake_responce(s); break;
639 case COMMAND_DISCONNECT: rws_socket_send_disconnect(s); break;
640 case COMMAND_IDLE:
641 if (s->is_connected) {
642 rws_socket_idle_send(s);
643 }
644
645 if (s->is_connected) {
646 rws_socket_idle_recv(s);
647 }
648 break;
649 default: break;
650 }
651
652 rws_mutex_unlock(s->work_mutex);
653 switch (s->command) {
654 case COMMAND_INFORM_CONNECTED:
655 s->command = COMMAND_IDLE;
656 if (s->on_connected) {
657 s->on_connected(s);
658 }
659 break;
660 case COMMAND_INFORM_DISCONNECTED: {
661 s->command = COMMAND_END;
662 rws_error last_error = rws_socket_get_error(s);
663 s->error = NULL;
664 rws_socket_send_disconnect(s);
665
666 if (s->error) {
667 rws_error_delete_clean(&s->error);
668 }
669 s->error = last_error;
670
671 if (s->on_disconnected) {
672 s->on_disconnected(s);
673 }
674 WRN("rws_socket_work_th_func COMMAND_INFORM_DISCONNECTED\n");
675 }
676 break;
677 case COMMAND_IDLE:
678 if (s->recvd_frames) {
679 rws_socket_inform_recvd_frames(s);
680 }
681 break;
682 default: break;
683 }
684 rws_thread_sleep(10);
685 }
686
687 rws_socket_close(s);
688 s->work_thread = NULL;
689 rws_sem_signal(s->exit_sem);
690 WRN("end rws_socket_work_th_func\n");
691 }
692
rws_socket_create_start_work_thread(rws_socket s)693 rws_bool rws_socket_create_start_work_thread(rws_socket s) {
694 rws_error_delete_clean(&s->error);
695 s->command = COMMAND_NONE;
696 s->work_thread = rws_thread_create(&rws_socket_work_th_func, s);
697 if (s->work_thread) {
698 s->command = COMMAND_CONNECT_TO_HOST;
699 return rws_true;
700 }
701 return rws_false;
702 }
703
rws_socket_resize_received(rws_socket s,const size_t need_size)704 void rws_socket_resize_received(rws_socket s, const size_t need_size) {
705 void * res = NULL;
706 size_t min = 0;
707 size_t size = MAX_THRESH_VAL;
708
709 if (need_size == s->received_size) {
710 return;
711 }
712
713 if (need_size > MAX_THRESH_VAL) {
714 size = need_size;
715 }
716
717 res = rws_malloc(size);
718 assert(res && (size > 0));
719
720 min = (s->received_size < size) ? s->received_size : size;
721 if (min > 0 && s->received) {
722 memcpy(res, s->received, min);
723 }
724 rws_free_clean(&s->received);
725 s->received = res;
726 s->received_size = size;
727 }
728
rws_socket_close(rws_socket s)729 void rws_socket_close(rws_socket s) {
730 s->received_len = 0;
731 if (s->socket != RWS_INVALID_SOCKET) {
732 #ifdef WEBSOCKET_SSL_ENABLE
733 if(s->scheme && strcmp(s->scheme, "wss") == 0)
734 rws_ssl_close(s);
735 else
736 #endif /* WEBSOCKET_SSL_ENABLE */
737 RWS_SOCK_CLOSE(s->socket);
738 s->socket = RWS_INVALID_SOCKET;
739 }
740 s->is_connected = rws_false;
741 }
742
rws_socket_append_recvd_frames(rws_socket s,_rws_frame * frame)743 void rws_socket_append_recvd_frames(rws_socket s, _rws_frame * frame) {
744 _rws_node_value frame_list_var;
745 frame_list_var.object = frame;
746
747 if (s->recvd_frames) {
748 rws_list_append(s->recvd_frames, frame_list_var);
749 } else {
750 s->recvd_frames = rws_list_create();
751 s->recvd_frames->value = frame_list_var;
752 }
753 }
754
rws_socket_append_send_frames(rws_socket s,_rws_frame * frame)755 void rws_socket_append_send_frames(rws_socket s, _rws_frame * frame) {
756 _rws_node_value frame_list_var;
757 frame_list_var.object = frame;
758 if (s->send_frames) {
759 rws_list_append(s->send_frames, frame_list_var);
760 } else {
761 s->send_frames = rws_list_create();
762 s->send_frames->value = frame_list_var;
763 }
764 }
765
rws_socket_send_text_priv(rws_socket s,const char * text)766 rws_bool rws_socket_send_text_priv(rws_socket s, const char * text) {
767 size_t len = text ? strlen(text) : 0;
768 _rws_frame * frame = NULL;
769
770 if (len <= 0) {
771 return rws_false;
772 }
773
774 frame = rws_frame_create();
775 frame->is_masked = rws_true;
776 frame->opcode = rws_opcode_text_frame;
777 rws_frame_fill_with_send_data(frame, text, len, rws_true);
778 rws_socket_append_send_frames(s, frame);
779
780 return rws_true;
781 }
782
rws_socket_send_bin_priv(rws_socket s,const char * bin,size_t size,rws_binary bin_type)783 rws_bool rws_socket_send_bin_priv(rws_socket s, const char * bin, size_t size, rws_binary bin_type)
784 {
785 _rws_frame * frame = NULL;
786
787 frame = rws_frame_create();
788 if (frame != NULL)
789 {
790 frame->is_masked = rws_true;
791 switch (bin_type)
792 {
793 case rws_binary_start:
794 //DBG("rws_binary_start\n");
795 frame->opcode = rws_opcode_binary_frame;
796 break;
797 case rws_binary_continue:
798 //DBG("rws_binary_continue\n");
799 frame->opcode = rws_opcode_continuation;
800 break;
801 case rws_binary_finish:
802 //DBG("rws_binary_finish\n");
803 frame->opcode = rws_opcode_continuation;
804 break;
805 }
806 litews_frame_fill_with_send_bin_data(frame, bin, size, bin_type);
807 rws_socket_append_send_frames(s, frame);
808
809 return rws_true;
810 }
811 else
812 {
813 /*Need to free data????*/
814 return rws_false;
815 }
816 }
817
rws_socket_send_bin_start_priv(rws_socket s,const char * bin,size_t len)818 rws_bool rws_socket_send_bin_start_priv(rws_socket s, const char *bin, size_t len) {
819 //CHECK_RET_WITH_RET(bin, rws_false);
820 _rws_frame * frame = NULL;
821
822 if (len <= 0) {
823 return rws_false;
824 }
825
826 frame = rws_frame_create();
827 frame->is_masked = rws_true;
828 frame->opcode = rws_opcode_binary_frame;
829 rws_frame_fill_with_send_data(frame, bin, len, rws_false);
830 rws_socket_append_send_frames(s, frame);
831
832 return rws_true;
833 }
834
rws_socket_send_bin_continue_priv(rws_socket s,const char * bin,size_t len)835 rws_bool rws_socket_send_bin_continue_priv(rws_socket s, const char *bin, size_t len) {
836 //CHECK_RET_WITH_RET(bin, rws_false);
837 _rws_frame * frame = NULL;
838
839 if (len <= 0) {
840 return rws_false;
841 }
842
843 frame = rws_frame_create();
844 frame->is_masked = rws_true;
845 frame->opcode = rws_opcode_continuation;
846 rws_frame_fill_with_send_data(frame, bin, len, rws_false);
847 rws_socket_append_send_frames(s, frame);
848
849 return rws_true;
850 }
851
rws_socket_send_bin_finish_priv(rws_socket s,const char * bin,size_t len)852 rws_bool rws_socket_send_bin_finish_priv(rws_socket s, const char *bin, size_t len) {
853 //CHECK_RET_WITH_RET(bin, rws_false);
854 _rws_frame * frame = NULL;
855
856 if (len <= 0) {
857 return rws_false;
858 }
859
860 frame = rws_frame_create();
861 frame->is_masked = rws_true;
862 frame->opcode = rws_opcode_continuation;
863 rws_frame_fill_with_send_data(frame, bin, len, rws_true);
864 rws_socket_append_send_frames(s, frame);
865
866 return rws_true;
867 }
868
rws_socket_delete_all_frames_in_list(_rws_list * list_with_frames)869 void rws_socket_delete_all_frames_in_list(_rws_list * list_with_frames) {
870 _rws_frame * frame = NULL;
871 _rws_node * cur = list_with_frames;
872 while (cur) {
873 frame = (_rws_frame *)cur->value.object;
874 if (frame) {
875 rws_frame_delete(frame);
876 }
877 cur->value.object = NULL;
878 cur = cur->next;
879 }
880 }
881
rws_socket_set_option(rws_socket_t s,int option,int value)882 void rws_socket_set_option(rws_socket_t s, int option, int value) {
883 setsockopt(s, SOL_SOCKET, option, (char *)&value, sizeof(int));
884 }
885
rws_socket_check_write_error(rws_socket s,int error_num)886 void rws_socket_check_write_error(rws_socket s, int error_num) {
887 int socket_code = 0, code = 0;
888 socklen_t socket_code_size = sizeof(socket_code);
889
890 if (s->socket != RWS_INVALID_SOCKET) {
891 if (getsockopt(s->socket, SOL_SOCKET, SO_ERROR, &socket_code, &socket_code_size) != 0) {
892 socket_code = 0;
893 }
894 }
895
896 code = (socket_code > 0) ? socket_code : error_num;
897 if (code <= 0) {
898 return;
899 }
900
901 switch (code) {
902 // send errors
903 case EACCES: //
904
905 // case EAGAIN: // The socket is marked nonblocking and the requested operation would block
906 // case EWOULDBLOCK: // The socket is marked nonblocking and the receive operation would block
907
908 case EBADF: // An invalid descriptor was specified
909 case ECONNRESET: // Connection reset by peer
910 case EDESTADDRREQ: // The socket is not connection-mode, and no peer address is set
911 case EFAULT: // An invalid user space address was specified for an argument
912 // The receive buffer pointer(s) point outside the process's address space.
913 case EINTR: // A signal occurred before any data was transmitted
914 // The receive was interrupted by delivery of a signal before any data were available
915 case EINVAL: // Invalid argument passed
916 case EISCONN: // The connection-mode socket was connected already but a recipient was specified
917 case EMSGSIZE: // The socket type requires that message be sent atomically, and the size of the message to be sent made this impossible
918 case ENOBUFS: // The output queue for a network interface was full
919 case ENOMEM: // No memory available
920 case ENOTCONN: // The socket is not connected, and no target has been given
921 // The socket is associated with a connection-oriented protocol and has not been connected
922 case ENOTSOCK: // The argument sockfd is not a socket
923 // The argument sockfd does not refer to a socket
924 case EOPNOTSUPP: // Some bit in the flags argument is inappropriate for the socket type.
925 case EPIPE: // The local end has been shut down on a connection oriented socket
926 // recv errors
927 case ECONNREFUSED: // A remote host refused to allow the network connection (typically because it is not running the requested service).
928
929 s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, rws_strerror(code));
930 break;
931
932 default:
933 break;
934 }
935 }
936
937 #ifdef WEBSOCKET_SSL_ENABLE
938 #if defined(MBEDTLS_DEBUG_C)
939 #define DEBUG_LEVEL 1
940 #endif
_rws_tls_net_init(mbedtls_net_context * ctx)941 static void _rws_tls_net_init( mbedtls_net_context *ctx )
942 {
943 ctx->fd = -1;
944 }
945
_rws_tls_net_free(mbedtls_net_context * ctx)946 static void _rws_tls_net_free( mbedtls_net_context *ctx )
947 {
948 if( ctx->fd == -1 )
949 return;
950
951 shutdown( ctx->fd, 2 );
952 close( ctx->fd );
953
954 ctx->fd = -1;
955 }
956
957 static int s_send_timeout_ms = WRITE_TIMEOUT_MS;
_rws_tls_net_send(void * ctx,const unsigned char * buf,size_t len)958 static int _rws_tls_net_send( void *ctx, const unsigned char *buf, size_t len )
959 {
960 int ret;
961
962 int fd = ((mbedtls_net_context *) ctx)->fd;
963 struct timeval interval = {s_send_timeout_ms / 1000, (s_send_timeout_ms % 1000) * 1000};
964
965 if( fd < 0 )
966 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
967
968 if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 100)) {
969 interval.tv_sec = 0;
970 interval.tv_usec = 10000;
971 }
972
973 #if 0 // FIXME: not support yet, need to fix it later
974 /*set send timeout to avoid send block*/
975 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&interval,
976 sizeof(struct timeval))) {
977 return -1;
978 }
979 #endif
980
981 ret = (int) send( fd, buf, len, 0);
982
983 if( ret < 0 )
984 {
985 if( errno == EPIPE || errno == ECONNRESET )
986 return( MBEDTLS_ERR_NET_CONN_RESET );
987
988 if( errno == EINTR )
989 return( MBEDTLS_ERR_SSL_WANT_WRITE );
990
991 return( MBEDTLS_ERR_NET_SEND_FAILED );
992 }
993
994 return( ret );
995 }
996
_rws_tls_net_recv(void * ctx,unsigned char * buf,size_t len)997 static int _rws_tls_net_recv( void *ctx, unsigned char *buf, size_t len )
998 {
999 int ret;
1000 int fd = ((mbedtls_net_context *) ctx)->fd;
1001
1002 if( fd < 0 )
1003 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
1004
1005 ret = (int) recv( fd, buf, len, 0);
1006 // DBG("@@ret:%d, errno:%d", ret, errno);
1007 if( ret < 0 )
1008 {
1009 // if( errno == EAGAIN )
1010 // return( MBEDTLS_ERR_SSL_WANT_READ );
1011
1012 if( errno == EPIPE || errno == ECONNRESET )
1013 return( MBEDTLS_ERR_NET_CONN_RESET );
1014
1015 if( errno == EINTR )
1016 return( MBEDTLS_ERR_SSL_WANT_READ );
1017
1018 return( MBEDTLS_ERR_NET_RECV_FAILED );
1019 }
1020
1021 return( ret );
1022 }
1023
_rws_tls_net_recv_timeout(void * ctx,unsigned char * buf,size_t len,uint32_t timeout)1024 static int _rws_tls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
1025 uint32_t timeout )
1026 {
1027 int ret;
1028 struct timeval tv;
1029 fd_set read_fds;
1030 int fd = ((mbedtls_net_context *) ctx)->fd;
1031
1032 if( fd < 0 )
1033 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
1034
1035 FD_ZERO( &read_fds );
1036 FD_SET( fd, &read_fds );
1037
1038 tv.tv_sec = timeout / 1000;
1039 tv.tv_usec = ( timeout % 1000 ) * 1000;
1040
1041 /* no wait if timeout == 0 */
1042 ret = select( fd + 1, &read_fds, NULL, NULL, &tv );
1043
1044 /* Zero fds ready means we timed out */
1045 if( ret == 0 )
1046 return( MBEDTLS_ERR_SSL_TIMEOUT );
1047
1048 if( ret < 0 )
1049 {
1050 if( errno == EINTR )
1051 return( MBEDTLS_ERR_SSL_WANT_READ );
1052
1053 return( MBEDTLS_ERR_NET_RECV_FAILED );
1054 }
1055
1056 /* This call will not block */
1057 return( _rws_tls_net_recv( ctx, buf, len ) );
1058 }
1059
transport_utils_random(unsigned char * output,size_t output_len)1060 static void transport_utils_random(unsigned char *output, size_t output_len)
1061 {
1062 #if defined(CONFIG_TEE_CA)
1063 csi_tee_rand_generate(output, output_len);
1064 #else
1065 int i;
1066 uint32_t random;
1067 int mod = output_len % 4;
1068 int count = 0;
1069 static uint32_t rnd = 0x12345;
1070 for (i = 0; i < output_len / 4; i++) {
1071 random = rnd * 0xFFFF777;
1072 rnd = random;
1073 output[count++] = (random >> 24) & 0xFF;
1074 output[count++] = (random >> 16) & 0xFF;
1075 output[count++] = (random >> 8) & 0xFF;
1076 output[count++] = (random) & 0xFF;
1077 }
1078 random = rnd * 0xFFFF777;
1079 rnd = random;
1080 for (i = 0; i < mod; i++) {
1081 output[i + count] = (random >> 8 * i) & 0xFF;
1082 }
1083 #endif
1084 }
1085
_rws_random(void * p_rng,unsigned char * output,size_t output_len)1086 static int _rws_random(void *p_rng, unsigned char *output, size_t output_len)
1087 {
1088 (void)p_rng;
1089 transport_utils_random(output, output_len);
1090 return 0;
1091 }
1092
_rws_debug(void * ctx,int level,const char * file,int line,const char * str)1093 static void _rws_debug( void *ctx, int level, const char *file, int line, const char *str )
1094 {
1095 DBG("%s", str);
1096 }
1097
rws_ssl_conn(rws_socket s)1098 int rws_ssl_conn(rws_socket s)
1099 {
1100 int authmode = MBEDTLS_SSL_VERIFY_NONE;
1101 // const char *pers = "https";
1102 int value, ret = 0;
1103 uint32_t flags;
1104 // char port[10] = {0};
1105 _rws_ssl *ssl;
1106
1107 s->ssl = rws_malloc_zero(sizeof(_rws_ssl));
1108 if (!s->ssl) {
1109 DBG("Memory malloc error.");
1110 ret = -1;
1111 goto exit;
1112 }
1113
1114 ssl = s->ssl;
1115
1116 if (s->server_cert)
1117 authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
1118
1119 /*
1120 * Initialize the RNG and the session data
1121 */
1122 #if defined(MBEDTLS_DEBUG_C)
1123 mbedtls_debug_set_threshold(DEBUG_LEVEL);
1124 #endif
1125 _rws_tls_net_init(&ssl->net_ctx);
1126 // mbedtls_net_init(&ssl->net_ctx);
1127 mbedtls_ssl_init(&ssl->ssl_ctx);
1128 mbedtls_ssl_config_init(&ssl->ssl_conf);
1129 mbedtls_x509_crt_init(&ssl->cacert);
1130 mbedtls_x509_crt_init(&ssl->clicert);
1131 mbedtls_pk_init(&ssl->pkey);
1132 /* mbedtls_ctr_drbg_init(&ssl->ctr_drbg);
1133 mbedtls_entropy_init(&ssl->entropy);
1134 if ((value = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg,
1135 mbedtls_entropy_func,
1136 &ssl->entropy,
1137 (const unsigned char*)pers,
1138 strlen(pers))) != 0) {
1139 DBG("mbedtls_ctr_drbg_seed() failed, value:-0x%x.", -value);
1140 ret = -1;
1141 goto exit;
1142 }
1143 */
1144
1145 /*
1146 * Load the Client certificate
1147 */
1148 if (s->client_cert && s->client_pk) {
1149 ret = mbedtls_x509_crt_parse(&ssl->clicert, (const unsigned char *)s->client_cert, s->client_cert_len);
1150 if (ret < 0) {
1151 ERR("Loading cli_cert failed! mbedtls_x509_crt_parse returned -0x%x.", -ret);
1152 ret = -1;
1153 goto exit;
1154 }
1155
1156 ret = mbedtls_pk_parse_key(&ssl->pkey, (const unsigned char *)s->client_pk, s->client_pk_len, NULL, 0);
1157 if (ret != 0) {
1158 ERR("failed! mbedtls_pk_parse_key returned -0x%x.", -ret);
1159 ret = -1;
1160 goto exit;
1161 }
1162 }
1163
1164 /*
1165 * Load the trusted CA
1166 */
1167 /* cert_len passed in is gotten from sizeof not strlen */
1168 if (s->server_cert && ((value = mbedtls_x509_crt_parse(&ssl->cacert,
1169 (const unsigned char *)s->server_cert,
1170 s->server_cert_len)) < 0)) {
1171 ERR("mbedtls_x509_crt_parse() failed, value:-0x%x.", -value);
1172 ret = -1;
1173 goto exit;
1174 }
1175
1176 /*
1177 * Start the connection
1178 */
1179 /*
1180 snprintf(port, sizeof(port), "%d", client->port) ;
1181 if ((ret = mbedtls_net_connect(&ssl->net_ctx, host, port, MBEDTLS_NET_PROTO_TCP)) != 0) {
1182 DBG("failed! mbedtls_net_connect returned %d, port:%s.", ret, port);
1183 goto exit;
1184 }*/
1185 DBG("start to connect to host");
1186 rws_socket_connect_to_host(s);
1187 if (s->socket == RWS_INVALID_SOCKET){
1188 ret = -1;
1189 ERR("failed! mbedtls_net_connect returned.");
1190 goto exit;
1191 } else {
1192 DBG("connect to host ok");
1193 ssl->net_ctx.fd = s->socket;
1194 }
1195
1196 /*
1197 * Setup stuff
1198 */
1199 if ((value = mbedtls_ssl_config_defaults(&ssl->ssl_conf,
1200 MBEDTLS_SSL_IS_CLIENT,
1201 MBEDTLS_SSL_TRANSPORT_STREAM,
1202 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
1203 ERR("mbedtls_ssl_config_defaults() failed, value:-0x%x.", -value);
1204 ret = -1;
1205 goto exit;
1206 }
1207 mbedtls_ssl_conf_read_timeout(&ssl->ssl_conf, READ_TIMEOUT_MS);
1208
1209 // TODO: add customerization encryption algorithm
1210 memcpy(&ssl->profile, ssl->ssl_conf.cert_profile, sizeof(mbedtls_x509_crt_profile));
1211 ssl->profile.allowed_mds = ssl->profile.allowed_mds | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_MD5);
1212 mbedtls_ssl_conf_cert_profile(&ssl->ssl_conf, &ssl->profile);
1213
1214 mbedtls_ssl_conf_authmode(&ssl->ssl_conf, authmode);
1215 mbedtls_ssl_conf_ca_chain(&ssl->ssl_conf, &ssl->cacert, NULL);
1216
1217 if (s->client_cert && (ret = mbedtls_ssl_conf_own_cert(&ssl->ssl_conf, &ssl->clicert, &ssl->pkey)) != 0) {
1218 ERR(" failed! mbedtls_ssl_conf_own_cert returned %d.", ret );
1219 ret = -1;
1220 goto exit;
1221 }
1222
1223 mbedtls_ssl_conf_rng(&ssl->ssl_conf, _rws_random, NULL);
1224 mbedtls_ssl_conf_dbg(&ssl->ssl_conf, _rws_debug, NULL);
1225 // mbedtls_ssl_conf_rng(&ssl->ssl_conf, mbedtls_ctr_drbg_random, &ssl->ctr_drbg);
1226
1227 if ((value = mbedtls_ssl_setup(&ssl->ssl_ctx, &ssl->ssl_conf)) != 0) {
1228 ERR("mbedtls_ssl_setup() failed, value:-0x%x.", -value);
1229 ret = -1;
1230 goto exit;
1231 }
1232
1233 mbedtls_ssl_set_bio(&ssl->ssl_ctx, &ssl->net_ctx, _rws_tls_net_send, _rws_tls_net_recv, _rws_tls_net_recv_timeout);
1234 // mbedtls_ssl_set_bio(&ssl->ssl_ctx, &ssl->net_ctx, mbedtls_net_send, mbedtls_net_recv, NULL);
1235 //mbedtls_net_set_block(&ssl->net_ctx);
1236
1237 DBG("start to handshake...");
1238 /*
1239 * Handshake
1240 */
1241 while ((ret = mbedtls_ssl_handshake(&ssl->ssl_ctx)) != 0) {
1242 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
1243 ERR("mbedtls_ssl_handshake() failed, ret:-0x%x.", -ret);
1244 ret = -1;
1245 goto exit;
1246 }
1247 }
1248 mbedtls_ssl_conf_read_timeout(&ssl->ssl_conf, 5);
1249
1250 /*
1251 * Verify the server certificate
1252 */
1253 /* In real life, we would have used MBEDTLS_SSL_VERIFY_REQUIRED so that the
1254 * handshake would not succeed if the peer's cert is bad. Even if we used
1255 * MBEDTLS_SSL_VERIFY_OPTIONAL, we would bail out here if ret != 0 */
1256 if ((flags = mbedtls_ssl_get_verify_result(&ssl->ssl_ctx)) != 0) {
1257 #if defined(MBEDTLS_DEBUG_C)
1258 char vrfy_buf[512];
1259 ERR("svr_cert varification failed. authmode:%d", authmode);
1260 mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags);
1261 DBG("%s", vrfy_buf);
1262 #endif
1263 ret = -1;
1264 }
1265 else {
1266 WRN("svr_cert varification ok. authmode:%d", authmode);
1267 }
1268
1269 exit:
1270 if(ret != 0) {
1271 DBG("ret=%d.", ret);
1272 s->error = rws_error_new_code_descr(rws_error_code_connect_to_host, "Failed connect to host");
1273 ERR("%s: code:%d, error:%s", __FUNCTION__, s->error->code, s->error->description);
1274 s->command = COMMAND_INFORM_DISCONNECTED;
1275 rws_ssl_close(s);
1276 }
1277 return ret;
1278 }
1279
rws_ssl_close(rws_socket s)1280 int rws_ssl_close(rws_socket s)
1281 {
1282 _rws_ssl *ssl = s->ssl;
1283
1284 if (!ssl)
1285 return -1;
1286
1287 s->ssl = NULL;
1288 s->client_cert = NULL;
1289 s->server_cert = NULL;
1290 s->client_pk = NULL;
1291
1292 mbedtls_ssl_close_notify(&ssl->ssl_ctx);
1293 _rws_tls_net_free(&ssl->net_ctx);
1294 // mbedtls_net_free(&ssl->net_ctx);
1295 mbedtls_x509_crt_free(&ssl->cacert);
1296 mbedtls_x509_crt_free(&ssl->clicert);
1297 mbedtls_pk_free(&ssl->pkey);
1298 mbedtls_ssl_free(&ssl->ssl_ctx);
1299 mbedtls_ssl_config_free(&ssl->ssl_conf);
1300 // mbedtls_ctr_drbg_free(&ssl->ctr_drbg);
1301 // mbedtls_entropy_free(&ssl->entropy);
1302
1303 rws_free(ssl);
1304 return 0;
1305 }
1306 #endif
1307