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