/tags/Footagehead-1.3.2/libwired/libwired/net/wi-socket.c

https://bitbucket.org/balrog/zanka-full · C · 1696 lines · 1093 code · 577 blank · 26 comment · 228 complexity · 116f45e6588c23e69ca7ac7b90b31f5c MD5 · raw file

  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2003-2009 Axel Andersson
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  19. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "config.h"
  28. #include <sys/param.h>
  29. #include <sys/types.h>
  30. #include <sys/time.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in.h>
  33. #ifdef HAVE_NETINET_IN_SYSTM_H
  34. #include <netinet/in_systm.h>
  35. #endif
  36. #ifdef HAVE_NETINET_IP_H
  37. #include <netinet/ip.h>
  38. #endif
  39. #include <netinet/tcp.h>
  40. #include <netdb.h>
  41. #include <net/if.h>
  42. #include <fcntl.h>
  43. #include <unistd.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <errno.h>
  47. #ifdef HAVE_OPENSSL_SSL_H
  48. #include <openssl/err.h>
  49. #include <openssl/ssl.h>
  50. #endif
  51. #ifdef HAVE_IFADDRS_H
  52. #include <ifaddrs.h>
  53. #endif
  54. #include <wired/wi-array.h>
  55. #include <wired/wi-assert.h>
  56. #include <wired/wi-address.h>
  57. #include <wired/wi-date.h>
  58. #include <wired/wi-macros.h>
  59. #include <wired/wi-lock.h>
  60. #include <wired/wi-private.h>
  61. #include <wired/wi-rsa.h>
  62. #include <wired/wi-socket.h>
  63. #include <wired/wi-string.h>
  64. #include <wired/wi-system.h>
  65. #include <wired/wi-thread.h>
  66. #include <wired/wi-x509.h>
  67. #define _WI_SOCKET_BUFFER_MAX_SIZE 131072
  68. struct _wi_socket_tls {
  69. wi_runtime_base_t base;
  70. #ifdef HAVE_OPENSSL_SSL_H
  71. SSL_CTX *ssl_ctx;
  72. DH *dh;
  73. wi_boolean_t private_key;
  74. #endif
  75. };
  76. struct _wi_socket {
  77. wi_runtime_base_t base;
  78. wi_address_t *address;
  79. wi_socket_type_t type;
  80. wi_uinteger_t direction;
  81. int sd;
  82. #ifdef HAVE_OPENSSL_SSL_H
  83. SSL *ssl;
  84. #endif
  85. void *data;
  86. wi_string_t *buffer;
  87. wi_boolean_t interactive;
  88. wi_boolean_t close;
  89. wi_boolean_t broken;
  90. };
  91. #if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS)
  92. static unsigned long _wi_socket_ssl_id_function(void);
  93. static void _wi_socket_ssl_locking_function(int, int, const char *, int);
  94. #endif
  95. #ifdef HAVE_OPENSSL_SSL_H
  96. static void _wi_socket_tls_dealloc(wi_runtime_instance_t *);
  97. #endif
  98. static void _wi_socket_dealloc(wi_runtime_instance_t *);
  99. static wi_string_t * _wi_socket_description(wi_runtime_instance_t *);
  100. static wi_boolean_t _wi_socket_set_option_int(wi_socket_t *, int, int, int);
  101. static wi_boolean_t _wi_socket_get_option_int(wi_socket_t *, int, int, int *);
  102. #if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS)
  103. static wi_array_t *_wi_socket_ssl_locks;
  104. #endif
  105. #ifdef HAVE_OPENSSL_SSL_H
  106. static wi_runtime_id_t _wi_socket_tls_runtime_id = WI_RUNTIME_ID_NULL;
  107. static wi_runtime_class_t _wi_socket_tls_runtime_class = {
  108. "wi_socket_tls_t",
  109. _wi_socket_tls_dealloc,
  110. NULL,
  111. NULL,
  112. NULL,
  113. NULL
  114. };
  115. #endif
  116. static wi_runtime_id_t _wi_socket_runtime_id = WI_RUNTIME_ID_NULL;
  117. static wi_runtime_class_t _wi_socket_runtime_class = {
  118. "wi_socket_t",
  119. _wi_socket_dealloc,
  120. NULL,
  121. NULL,
  122. _wi_socket_description,
  123. NULL
  124. };
  125. void wi_socket_register(void) {
  126. #ifdef HAVE_OPENSSL_SSL_H
  127. _wi_socket_tls_runtime_id = wi_runtime_register_class(&_wi_socket_tls_runtime_class);
  128. #endif
  129. _wi_socket_runtime_id = wi_runtime_register_class(&_wi_socket_runtime_class);
  130. }
  131. void wi_socket_initialize(void) {
  132. #ifdef HAVE_OPENSSL_SSL_H
  133. #ifdef WI_PTHREADS
  134. wi_lock_t *lock;
  135. wi_uinteger_t i, count;
  136. #endif
  137. SSL_library_init();
  138. #ifdef WI_PTHREADS
  139. count = CRYPTO_num_locks();
  140. _wi_socket_ssl_locks = wi_array_init_with_capacity(wi_array_alloc(), count);
  141. for(i = 0; i < count; i++) {
  142. lock = wi_lock_init(wi_lock_alloc());
  143. wi_array_add_data(_wi_socket_ssl_locks, lock);
  144. wi_release(lock);
  145. }
  146. CRYPTO_set_id_callback(_wi_socket_ssl_id_function);
  147. CRYPTO_set_locking_callback(_wi_socket_ssl_locking_function);
  148. #endif
  149. #endif
  150. }
  151. #pragma mark -
  152. #if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS)
  153. static unsigned long _wi_socket_ssl_id_function(void) {
  154. return ((unsigned long) wi_thread_current_thread());
  155. }
  156. static void _wi_socket_ssl_locking_function(int mode, int n, const char *file, int line) {
  157. wi_lock_t *lock;
  158. lock = WI_ARRAY(_wi_socket_ssl_locks, n);
  159. if(mode & CRYPTO_LOCK)
  160. wi_lock_lock(lock);
  161. else
  162. wi_lock_unlock(lock);
  163. }
  164. #endif
  165. #pragma mark -
  166. void wi_socket_exit_thread(void) {
  167. #ifdef HAVE_OPENSSL_SSL_H
  168. ERR_remove_state(0);
  169. #endif
  170. }
  171. #pragma mark -
  172. #ifdef HAVE_OPENSSL_SSL_H
  173. wi_runtime_id_t wi_socket_tls_runtime_id(void) {
  174. return _wi_socket_tls_runtime_id;
  175. }
  176. #pragma mark -
  177. wi_socket_tls_t * wi_socket_tls_alloc(void) {
  178. return wi_runtime_create_instance(_wi_socket_tls_runtime_id, sizeof(wi_socket_tls_t));
  179. }
  180. wi_socket_tls_t * wi_socket_tls_init_with_type(wi_socket_tls_t *tls, wi_socket_tls_type_t type) {
  181. SSL_METHOD *method;
  182. switch(type) {
  183. default:
  184. case WI_SOCKET_TLS_CLIENT:
  185. method = TLSv1_client_method();
  186. break;
  187. case WI_SOCKET_TLS_SERVER:
  188. method = TLSv1_server_method();
  189. break;
  190. }
  191. tls->ssl_ctx = SSL_CTX_new(method);
  192. if(!tls->ssl_ctx) {
  193. wi_error_set_openssl_error();
  194. wi_release(NULL);
  195. return NULL;
  196. }
  197. SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY);
  198. SSL_CTX_set_quiet_shutdown(tls->ssl_ctx, 1);
  199. return tls;
  200. }
  201. static void _wi_socket_tls_dealloc(wi_runtime_instance_t *instance) {
  202. wi_socket_tls_t *tls = instance;
  203. if(tls->ssl_ctx)
  204. SSL_CTX_free(tls->ssl_ctx);
  205. if(tls->dh)
  206. DH_free(tls->dh);
  207. }
  208. #pragma mark -
  209. wi_boolean_t wi_socket_tls_set_certificate(wi_socket_tls_t *tls, wi_x509_t *x509) {
  210. if(SSL_CTX_use_certificate(tls->ssl_ctx, wi_x509_x509(x509)) != 1) {
  211. wi_error_set_openssl_error();
  212. return false;
  213. }
  214. return true;
  215. }
  216. wi_boolean_t wi_socket_tls_set_private_key(wi_socket_tls_t *tls, wi_rsa_t *rsa) {
  217. tls->private_key = false;
  218. if(SSL_CTX_use_RSAPrivateKey(tls->ssl_ctx, wi_rsa_rsa(rsa)) != 1) {
  219. wi_error_set_openssl_error();
  220. return false;
  221. }
  222. tls->private_key = true;
  223. return true;
  224. }
  225. wi_boolean_t wi_socket_tls_set_ciphers(wi_socket_tls_t *tls, wi_string_t *ciphers) {
  226. if(SSL_CTX_set_cipher_list(tls->ssl_ctx, wi_string_cstring(ciphers)) != 1) {
  227. wi_error_set_libwired_error(WI_ERROR_SOCKET_NOVALIDCIPHER);
  228. return false;
  229. }
  230. return true;
  231. }
  232. wi_boolean_t wi_socket_tls_set_dh(wi_socket_tls_t *tls, const unsigned char *p, size_t p_size, const unsigned char *g, size_t g_size) {
  233. tls->dh = DH_new();
  234. if(!tls->dh) {
  235. wi_error_set_openssl_error();
  236. return false;
  237. }
  238. tls->dh->p = BN_bin2bn(p, p_size, NULL);
  239. tls->dh->g = BN_bin2bn(g, g_size, NULL);
  240. if(!tls->dh->p || !tls->dh->g) {
  241. wi_error_set_openssl_error();
  242. DH_free(tls->dh);
  243. tls->dh = NULL;
  244. return false;
  245. }
  246. return true;
  247. }
  248. #endif
  249. #pragma mark -
  250. wi_runtime_id_t wi_socket_runtime_id(void) {
  251. return _wi_socket_runtime_id;
  252. }
  253. #pragma mark -
  254. wi_socket_t * wi_socket_with_address(wi_address_t *address, wi_socket_type_t type) {
  255. return wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, type));
  256. }
  257. #pragma mark -
  258. wi_socket_t * wi_socket_alloc(void) {
  259. return wi_runtime_create_instance(_wi_socket_runtime_id, sizeof(wi_socket_t));
  260. }
  261. wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) {
  262. _socket->address = wi_copy(address);
  263. _socket->close = true;
  264. _socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
  265. _socket->type = type;
  266. _socket->sd = socket(wi_address_family(_socket->address), _socket->type, 0);
  267. if(_socket->sd < 0) {
  268. wi_error_set_errno(errno);
  269. wi_release(_socket);
  270. return NULL;
  271. }
  272. if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
  273. wi_release(_socket);
  274. return NULL;
  275. }
  276. #ifdef SO_REUSEPORT
  277. if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEPORT, 1)) {
  278. wi_release(_socket);
  279. return NULL;
  280. }
  281. #endif
  282. return _socket;
  283. }
  284. wi_socket_t * wi_socket_init_with_descriptor(wi_socket_t *socket, int sd) {
  285. socket->sd = sd;
  286. socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
  287. return socket;
  288. }
  289. static void _wi_socket_dealloc(wi_runtime_instance_t *instance) {
  290. wi_socket_t *socket = instance;
  291. wi_socket_close(socket);
  292. wi_release(socket->address);
  293. wi_release(socket->buffer);
  294. }
  295. static wi_string_t * _wi_socket_description(wi_runtime_instance_t *instance) {
  296. wi_socket_t *socket = instance;
  297. return wi_string_with_format(WI_STR("<%@ %p>{sd = %d, address = %@}"),
  298. wi_runtime_class_name(socket),
  299. socket,
  300. socket->sd,
  301. socket->address);
  302. }
  303. #pragma mark -
  304. static wi_boolean_t _wi_socket_set_option_int(wi_socket_t *socket, int level, int name, int option) {
  305. if(setsockopt(socket->sd, level, name, &option, sizeof(option)) < 0) {
  306. wi_error_set_errno(errno);
  307. return false;
  308. }
  309. return true;
  310. }
  311. static wi_boolean_t _wi_socket_get_option_int(wi_socket_t *socket, int level, int name, int *option) {
  312. socklen_t length;
  313. length = sizeof(*option);
  314. if(getsockopt(socket->sd, level, name, option, &length) < 0) {
  315. wi_error_set_errno(errno);
  316. *option = 0;
  317. return false;
  318. }
  319. return true;
  320. }
  321. #pragma mark -
  322. wi_address_t * wi_socket_address(wi_socket_t *socket) {
  323. return socket->address;
  324. }
  325. int wi_socket_descriptor(wi_socket_t *socket) {
  326. return socket->sd;
  327. }
  328. void * wi_socket_ssl(wi_socket_t *socket) {
  329. #ifdef HAVE_OPENSSL_SSL_H
  330. return socket->ssl;
  331. #else
  332. return NULL;
  333. #endif
  334. }
  335. wi_rsa_t * wi_socket_ssl_public_key(wi_socket_t *socket) {
  336. #ifdef HAVE_OPENSSL_SSL_H
  337. RSA *rsa = NULL;
  338. X509 *x509 = NULL;
  339. EVP_PKEY *pkey = NULL;
  340. x509 = SSL_get_peer_certificate(socket->ssl);
  341. if(!x509) {
  342. wi_error_set_openssl_error();
  343. goto end;
  344. }
  345. pkey = X509_get_pubkey(x509);
  346. if(!pkey) {
  347. wi_error_set_openssl_error();
  348. goto end;
  349. }
  350. rsa = EVP_PKEY_get1_RSA(pkey);
  351. if(!rsa)
  352. wi_error_set_openssl_error();
  353. end:
  354. if(x509)
  355. X509_free(x509);
  356. if(pkey)
  357. EVP_PKEY_free(pkey);
  358. return wi_autorelease(wi_rsa_init_with_rsa(wi_rsa_alloc(), rsa));
  359. #else
  360. return NULL;
  361. #endif
  362. }
  363. wi_string_t * wi_socket_cipher_version(wi_socket_t *socket) {
  364. #ifdef HAVE_OPENSSL_SSL_H
  365. return wi_string_with_cstring(SSL_get_cipher_version(socket->ssl));
  366. #else
  367. return NULL;
  368. #endif
  369. }
  370. wi_string_t * wi_socket_cipher_name(wi_socket_t *socket) {
  371. #ifdef HAVE_OPENSSL_SSL_H
  372. return wi_string_with_cstring(SSL_get_cipher_name(socket->ssl));
  373. #else
  374. return NULL;
  375. #endif
  376. }
  377. wi_uinteger_t wi_socket_cipher_bits(wi_socket_t *socket) {
  378. #ifdef HAVE_OPENSSL_SSL_H
  379. return SSL_get_cipher_bits(socket->ssl, NULL);
  380. #else
  381. return 0;
  382. #endif
  383. }
  384. wi_string_t * wi_socket_certificate_name(wi_socket_t *socket) {
  385. #ifdef HAVE_OPENSSL_SSL_H
  386. X509 *x509 = NULL;
  387. EVP_PKEY *pkey = NULL;
  388. wi_string_t *string = NULL;
  389. x509 = SSL_get_peer_certificate(socket->ssl);
  390. if(!x509)
  391. goto end;
  392. pkey = X509_get_pubkey(x509);
  393. if(!pkey)
  394. goto end;
  395. switch(EVP_PKEY_type(pkey->type)) {
  396. case EVP_PKEY_RSA:
  397. string = wi_string_init_with_cstring(wi_string_alloc(), "RSA");
  398. break;
  399. case EVP_PKEY_DSA:
  400. string = wi_string_init_with_cstring(wi_string_alloc(), "DSA");
  401. break;
  402. case EVP_PKEY_DH:
  403. string = wi_string_init_with_cstring(wi_string_alloc(), "DH");
  404. break;
  405. default:
  406. break;
  407. }
  408. end:
  409. if(x509)
  410. X509_free(x509);
  411. if(pkey)
  412. EVP_PKEY_free(pkey);
  413. return wi_autorelease(string);
  414. #else
  415. return NULL;
  416. #endif
  417. }
  418. wi_uinteger_t wi_socket_certificate_bits(wi_socket_t *socket) {
  419. #ifdef HAVE_OPENSSL_SSL_H
  420. X509 *x509 = NULL;
  421. EVP_PKEY *pkey = NULL;
  422. wi_uinteger_t bits = 0;
  423. x509 = SSL_get_peer_certificate(socket->ssl);
  424. if(!x509)
  425. goto end;
  426. pkey = X509_get_pubkey(x509);
  427. if(!pkey)
  428. goto end;
  429. bits = 8 * EVP_PKEY_size(pkey);
  430. end:
  431. if(x509)
  432. X509_free(x509);
  433. if(pkey)
  434. EVP_PKEY_free(pkey);
  435. return bits;
  436. #else
  437. return 0;
  438. #endif
  439. }
  440. wi_string_t * wi_socket_certificate_hostname(wi_socket_t *socket) {
  441. #ifdef HAVE_OPENSSL_SSL_H
  442. X509 *x509;
  443. wi_string_t *string;
  444. char hostname[MAXHOSTNAMELEN];
  445. x509 = SSL_get_peer_certificate(socket->ssl);
  446. if(!x509)
  447. return NULL;
  448. X509_NAME_get_text_by_NID(X509_get_subject_name(x509),
  449. NID_commonName,
  450. hostname,
  451. sizeof(hostname));
  452. string = wi_string_init_with_cstring(wi_string_alloc(), hostname);
  453. X509_free(x509);
  454. return wi_autorelease(string);
  455. #else
  456. return NULL;
  457. #endif
  458. }
  459. #pragma mark -
  460. void wi_socket_set_port(wi_socket_t *socket, wi_uinteger_t port) {
  461. wi_address_set_port(socket->address, port);
  462. }
  463. wi_uinteger_t wi_socket_port(wi_socket_t *socket) {
  464. return wi_address_port(socket->address);
  465. }
  466. void wi_socket_set_direction(wi_socket_t *socket, wi_uinteger_t direction) {
  467. socket->direction = direction;
  468. }
  469. wi_uinteger_t wi_socket_direction(wi_socket_t *socket) {
  470. return socket->direction;
  471. }
  472. void wi_socket_set_data(wi_socket_t *socket, void *data) {
  473. socket->data = data;
  474. }
  475. void * wi_socket_data(wi_socket_t *socket) {
  476. return socket->data;
  477. }
  478. wi_boolean_t wi_socket_set_blocking(wi_socket_t *socket, wi_boolean_t blocking) {
  479. int flags;
  480. flags = fcntl(socket->sd, F_GETFL);
  481. if(flags < 0) {
  482. wi_error_set_errno(errno);
  483. return false;
  484. }
  485. if(blocking)
  486. flags &= ~O_NONBLOCK;
  487. else
  488. flags |= O_NONBLOCK;
  489. if(fcntl(socket->sd, F_SETFL, flags) < 0) {
  490. wi_error_set_errno(errno);
  491. return false;
  492. }
  493. return true;
  494. }
  495. wi_boolean_t wi_socket_blocking(wi_socket_t *socket) {
  496. int flags;
  497. flags = fcntl(socket->sd, F_GETFL);
  498. if(flags < 0) {
  499. wi_error_set_errno(errno);
  500. return false;
  501. }
  502. return !(flags & O_NONBLOCK);
  503. }
  504. wi_boolean_t wi_socket_set_timeout(wi_socket_t *socket, wi_time_interval_t interval) {
  505. struct timeval tv;
  506. tv = wi_dtotv(interval);
  507. if(setsockopt(socket->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
  508. wi_error_set_errno(errno);
  509. return false;
  510. }
  511. if(setsockopt(socket->sd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
  512. wi_error_set_errno(errno);
  513. return false;
  514. }
  515. return true;
  516. }
  517. wi_time_interval_t wi_socket_timeout(wi_socket_t *socket) {
  518. struct timeval tv;
  519. socklen_t length;
  520. length = sizeof(tv);
  521. if(getsockopt(socket->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, &length) < 0) {
  522. wi_error_set_errno(errno);
  523. return 0.0;
  524. }
  525. return wi_tvtod(tv);
  526. }
  527. void wi_socket_set_interactive(wi_socket_t *socket, wi_boolean_t interactive) {
  528. _wi_socket_set_option_int(socket, IPPROTO_TCP, TCP_NODELAY, interactive ? 1 : 0);
  529. #if defined(IPTOS_LOWDELAY) && defined(IPTOS_THROUGHPUT)
  530. if(wi_address_family(socket->address) == WI_ADDRESS_IPV4)
  531. _wi_socket_set_option_int(socket, IPPROTO_IP, IP_TOS, interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT);
  532. #endif
  533. socket->interactive = interactive;
  534. }
  535. wi_boolean_t wi_socket_interactive(wi_socket_t *socket) {
  536. return socket->interactive;
  537. }
  538. int wi_socket_error(wi_socket_t *socket) {
  539. int error;
  540. WI_ASSERT(socket->type == WI_SOCKET_TCP, "%@ is not a TCP socket", socket);
  541. if(!_wi_socket_get_option_int(socket, SOL_SOCKET, SO_ERROR, &error))
  542. return errno;
  543. return error;
  544. }
  545. #pragma mark -
  546. wi_socket_t * wi_socket_wait_multiple(wi_array_t *array, wi_time_interval_t timeout) {
  547. wi_enumerator_t *enumerator;
  548. wi_socket_t *socket, *waiting_socket = NULL;
  549. struct timeval tv;
  550. fd_set rfds, wfds;
  551. int state, max_sd;
  552. tv = wi_dtotv(timeout);
  553. max_sd = -1;
  554. FD_ZERO(&rfds);
  555. FD_ZERO(&wfds);
  556. wi_array_rdlock(array);
  557. enumerator = wi_array_data_enumerator(array);
  558. while((socket = wi_enumerator_next_data(enumerator))) {
  559. if(wi_string_length(socket->buffer) > 0) {
  560. waiting_socket = socket;
  561. break;
  562. }
  563. if(socket->direction & WI_SOCKET_READ)
  564. FD_SET(socket->sd, &rfds);
  565. if(socket->direction & WI_SOCKET_WRITE)
  566. FD_SET(socket->sd, &wfds);
  567. if(socket->sd > max_sd)
  568. max_sd = socket->sd;
  569. }
  570. wi_array_unlock(array);
  571. if(waiting_socket)
  572. return waiting_socket;
  573. state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
  574. if(state < 0) {
  575. wi_error_set_errno(errno);
  576. return NULL;
  577. }
  578. wi_array_rdlock(array);
  579. enumerator = wi_array_data_enumerator(array);
  580. while((socket = wi_enumerator_next_data(enumerator))) {
  581. if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) {
  582. waiting_socket = socket;
  583. break;
  584. }
  585. }
  586. wi_array_unlock(array);
  587. return waiting_socket;
  588. }
  589. wi_socket_state_t wi_socket_wait(wi_socket_t *socket, wi_time_interval_t timeout) {
  590. if(wi_string_length(socket->buffer) > 0)
  591. return WI_SOCKET_READY;
  592. return wi_socket_wait_descriptor(socket->sd,
  593. timeout,
  594. (socket->direction & WI_SOCKET_READ),
  595. (socket->direction & WI_SOCKET_WRITE));
  596. }
  597. wi_socket_state_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
  598. struct timeval tv;
  599. fd_set rfds, wfds;
  600. int state;
  601. tv = wi_dtotv(timeout);
  602. FD_ZERO(&rfds);
  603. FD_ZERO(&wfds);
  604. if(read)
  605. FD_SET(sd, &rfds);
  606. if(write)
  607. FD_SET(sd, &wfds);
  608. state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
  609. if(state < 0) {
  610. wi_error_set_errno(errno);
  611. return WI_SOCKET_ERROR;
  612. }
  613. if(state == 0)
  614. return WI_SOCKET_TIMEOUT;
  615. return WI_SOCKET_READY;
  616. }
  617. #pragma mark -
  618. wi_boolean_t wi_socket_listen(wi_socket_t *socket, wi_uinteger_t backlog) {
  619. struct sockaddr *sa;
  620. struct sockaddr_storage ss;
  621. wi_uinteger_t port;
  622. socklen_t length;
  623. port = wi_address_port(socket->address);
  624. sa = wi_address_sa(socket->address);
  625. length = wi_address_sa_length(socket->address);
  626. if(bind(socket->sd, sa, length) < 0) {
  627. wi_error_set_errno(errno);
  628. return false;
  629. }
  630. if(socket->type == WI_SOCKET_TCP) {
  631. if(listen(socket->sd, backlog) < 0) {
  632. wi_error_set_errno(errno);
  633. return false;
  634. }
  635. }
  636. if(port == 0) {
  637. length = sizeof(ss);
  638. if(getsockname(socket->sd, (struct sockaddr *) &ss, &length) == 0) {
  639. wi_release(socket->address);
  640. socket->address = wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss);
  641. }
  642. }
  643. socket->direction = WI_SOCKET_READ;
  644. return true;
  645. }
  646. wi_boolean_t wi_socket_connect(wi_socket_t *socket, wi_time_interval_t timeout) {
  647. struct sockaddr *sa;
  648. wi_socket_state_t state;
  649. wi_uinteger_t length;
  650. int err;
  651. wi_boolean_t blocking;
  652. sa = wi_address_sa(socket->address);
  653. length = wi_address_sa_length(socket->address);
  654. if(timeout > 0.0) {
  655. blocking = wi_socket_blocking(socket);
  656. if(blocking)
  657. wi_socket_set_blocking(socket, false);
  658. err = connect(socket->sd, sa, length);
  659. if(err < 0) {
  660. if(errno != EINPROGRESS) {
  661. wi_error_set_errno(errno);
  662. return false;
  663. }
  664. do {
  665. state = wi_socket_wait_descriptor(socket->sd, 1.0, true, true);
  666. timeout -= 1.0;
  667. } while(state == WI_SOCKET_TIMEOUT && timeout >= 0.0);
  668. if(state == WI_SOCKET_ERROR)
  669. return false;
  670. if(timeout <= 0.0) {
  671. wi_error_set_errno(ETIMEDOUT);
  672. return false;
  673. }
  674. err = wi_socket_error(socket);
  675. if(err != 0) {
  676. wi_error_set_errno(err);
  677. return false;
  678. }
  679. }
  680. if(blocking)
  681. wi_socket_set_blocking(socket, true);
  682. } else {
  683. if(connect(socket->sd, sa, length) < 0) {
  684. wi_error_set_errno(errno);
  685. return false;
  686. }
  687. }
  688. socket->direction = WI_SOCKET_READ;
  689. return true;
  690. }
  691. #ifdef HAVE_OPENSSL_SSL_H
  692. wi_boolean_t wi_socket_connect_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) {
  693. wi_socket_state_t state;
  694. int err, result;
  695. wi_boolean_t blocking;
  696. socket->ssl = SSL_new(tls->ssl_ctx);
  697. if(!socket->ssl) {
  698. wi_error_set_openssl_error();
  699. return false;
  700. }
  701. if(SSL_set_fd(socket->ssl, socket->sd) != 1) {
  702. wi_error_set_openssl_error();
  703. return false;
  704. }
  705. if(timeout > 0.0) {
  706. blocking = wi_socket_blocking(socket);
  707. if(blocking)
  708. wi_socket_set_blocking(socket, false);
  709. result = SSL_connect(socket->ssl);
  710. if(result != 1) {
  711. do {
  712. err = SSL_get_error(socket->ssl, result);
  713. if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
  714. wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
  715. return false;
  716. }
  717. state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE));
  718. if(state == WI_SOCKET_ERROR)
  719. break;
  720. else if(state == WI_SOCKET_READY) {
  721. result = SSL_connect(socket->ssl);
  722. if(result == 1)
  723. break;
  724. }
  725. timeout -= 1.0;
  726. } while(timeout >= 0.0);
  727. if(state == WI_SOCKET_ERROR)
  728. return false;
  729. if(timeout <= 0.0) {
  730. wi_error_set_errno(ETIMEDOUT);
  731. return false;
  732. }
  733. }
  734. if(blocking)
  735. wi_socket_set_blocking(socket, true);
  736. } else {
  737. result = SSL_connect(socket->ssl);
  738. if(result != 1) {
  739. wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
  740. return false;
  741. }
  742. }
  743. return true;
  744. }
  745. #endif
  746. wi_socket_t * wi_socket_accept_multiple(wi_array_t *array, wi_time_interval_t timeout, wi_address_t **address) {
  747. wi_socket_t *socket;
  748. *address = NULL;
  749. socket = wi_socket_wait_multiple(array, 0.0);
  750. if(!socket)
  751. return NULL;
  752. return wi_socket_accept(socket, timeout, address);
  753. }
  754. wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_time_interval_t timeout, wi_address_t **address) {
  755. wi_socket_t *socket;
  756. struct sockaddr_storage ss;
  757. socklen_t length;
  758. int sd, err = 0;
  759. length = sizeof(ss);
  760. sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length);
  761. if(sd < 0)
  762. err = errno;
  763. *address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
  764. if(sd < 0) {
  765. wi_error_set_errno(err);
  766. return NULL;
  767. }
  768. socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd);
  769. socket->close = true;
  770. socket->address = wi_retain(*address);
  771. socket->type = accept_socket->type;
  772. socket->direction = WI_SOCKET_READ;
  773. socket->interactive = accept_socket->interactive;
  774. return wi_autorelease(socket);
  775. }
  776. #ifdef HAVE_OPENSSL_SSL_H
  777. wi_boolean_t wi_socket_accept_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) {
  778. wi_socket_state_t state;
  779. int err, result;
  780. wi_boolean_t blocking;
  781. socket->ssl = SSL_new(tls->ssl_ctx);
  782. if(!socket->ssl) {
  783. wi_error_set_openssl_error();
  784. return false;
  785. }
  786. if(SSL_set_fd(socket->ssl, socket->sd) != 1) {
  787. wi_error_set_openssl_error();
  788. return false;
  789. }
  790. if(!tls->private_key && tls->dh) {
  791. if(SSL_set_tmp_dh(socket->ssl, tls->dh) != 1) {
  792. wi_error_set_openssl_error();
  793. return false;
  794. }
  795. }
  796. if(timeout > 0.0) {
  797. blocking = wi_socket_blocking(socket);
  798. if(blocking)
  799. wi_socket_set_blocking(socket, false);
  800. result = SSL_accept(socket->ssl);
  801. if(result != 1) {
  802. do {
  803. err = SSL_get_error(socket->ssl, result);
  804. if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
  805. wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
  806. return false;
  807. }
  808. state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE));
  809. if(state == WI_SOCKET_ERROR)
  810. break;
  811. else if(state == WI_SOCKET_READY) {
  812. result = SSL_accept(socket->ssl);
  813. if(result == 1)
  814. break;
  815. }
  816. timeout -= 1.0;
  817. } while(timeout >= 0.0);
  818. if(state == WI_SOCKET_ERROR)
  819. return false;
  820. if(timeout <= 0.0) {
  821. wi_error_set_errno(ETIMEDOUT);
  822. return false;
  823. }
  824. }
  825. if(blocking)
  826. wi_socket_set_blocking(socket, true);
  827. } else {
  828. result = SSL_accept(socket->ssl);
  829. if(result != 1) {
  830. wi_error_set_openssl_ssl_error_with_result(socket->ssl, result);
  831. return false;
  832. }
  833. }
  834. return true;
  835. }
  836. #endif
  837. void wi_socket_close(wi_socket_t *socket) {
  838. #ifdef HAVE_OPENSSL_SSL_H
  839. if(socket->ssl) {
  840. if(!socket->broken) {
  841. if(SSL_shutdown(socket->ssl) == 0)
  842. SSL_shutdown(socket->ssl);
  843. }
  844. SSL_free(socket->ssl);
  845. socket->ssl = NULL;
  846. }
  847. #endif
  848. if(socket->close && socket->sd >= 0) {
  849. close(socket->sd);
  850. socket->sd = -1;
  851. }
  852. }
  853. #pragma mark -
  854. wi_integer_t wi_socket_sendto_format(wi_socket_t *socket, wi_string_t *fmt, ...) {
  855. wi_string_t *string;
  856. int bytes;
  857. va_list ap;
  858. va_start(ap, fmt);
  859. string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
  860. va_end(ap);
  861. bytes = wi_socket_sendto_buffer(socket, wi_string_cstring(string), wi_string_length(string));
  862. wi_release(string);
  863. return bytes;
  864. }
  865. wi_integer_t wi_socket_sendto_data(wi_socket_t *socket, wi_data_t *data) {
  866. return wi_socket_sendto_buffer(socket, wi_data_bytes(data), wi_data_length(data));
  867. }
  868. wi_integer_t wi_socket_sendto_buffer(wi_socket_t *socket, const char *buffer, size_t length) {
  869. wi_address_t *address;
  870. char *outbuffer = NULL;
  871. wi_integer_t bytes;
  872. address = wi_socket_address(socket);
  873. bytes = sendto(socket->sd, buffer, length, 0,
  874. wi_address_sa(address), wi_address_sa_length(address));
  875. if(bytes < 0) {
  876. wi_error_set_errno(errno);
  877. goto end;
  878. }
  879. end:
  880. if(outbuffer)
  881. wi_free(outbuffer);
  882. return bytes;
  883. }
  884. wi_integer_t wi_socket_recvfrom_multiple(wi_array_t *array, char *buffer, size_t length, wi_address_t **address) {
  885. wi_socket_t *socket;
  886. *address = NULL;
  887. socket = wi_socket_wait_multiple(array, 0.0);
  888. if(!socket)
  889. return -1;
  890. return wi_socket_recvfrom(socket, buffer, length, address);
  891. }
  892. wi_integer_t wi_socket_recvfrom(wi_socket_t *socket, char *buffer, size_t length, wi_address_t **address) {
  893. struct sockaddr_storage ss;
  894. char *inbuffer = NULL;
  895. socklen_t sslength;
  896. wi_integer_t bytes;
  897. sslength = sizeof(ss);
  898. bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength);
  899. if(bytes < 0) {
  900. wi_error_set_errno(errno);
  901. goto end;
  902. }
  903. end:
  904. *address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
  905. if(inbuffer)
  906. wi_free(inbuffer);
  907. return bytes;
  908. }
  909. #pragma mark -
  910. wi_integer_t wi_socket_write_format(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *fmt, ...) {
  911. wi_string_t *string;
  912. wi_integer_t bytes;
  913. va_list ap;
  914. va_start(ap, fmt);
  915. string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
  916. va_end(ap);
  917. bytes = wi_socket_write_buffer(socket, timeout, wi_string_cstring(string), wi_string_length(string));
  918. wi_release(string);
  919. return bytes;
  920. }
  921. wi_integer_t wi_socket_write_buffer(wi_socket_t *socket, wi_time_interval_t timeout, const void *buffer, size_t length) {
  922. wi_time_interval_t interval;
  923. wi_socket_state_t state;
  924. wi_uinteger_t offset;
  925. wi_integer_t bytes;
  926. WI_ASSERT(buffer != NULL, "buffer of length %u should not be NULL", length);
  927. if(timeout > 0.0) {
  928. state = wi_socket_wait_descriptor(socket->sd, timeout, false, true);
  929. if(state != WI_SOCKET_READY) {
  930. if(state == WI_SOCKET_TIMEOUT)
  931. wi_error_set_errno(ETIMEDOUT);
  932. return -1;
  933. }
  934. }
  935. interval = 0.0;
  936. #ifdef HAVE_OPENSSL_SSL_H
  937. if(socket->ssl) {
  938. do {
  939. bytes = SSL_write(socket->ssl, buffer, length);
  940. if(bytes <= 0) {
  941. if(bytes < 0 && SSL_get_error(socket->ssl, bytes) == SSL_ERROR_WANT_WRITE) {
  942. wi_thread_sleep(0.1);
  943. if(timeout > 0.0) {
  944. interval += 0.1;
  945. if(interval >= timeout) {
  946. wi_error_set_errno(ETIMEDOUT);
  947. break;
  948. }
  949. }
  950. } else {
  951. wi_error_set_openssl_ssl_error_with_result(socket->ssl, bytes);
  952. socket->broken = true;
  953. break;
  954. }
  955. }
  956. } while(bytes <= 0);
  957. return bytes;
  958. } else {
  959. #endif
  960. offset = 0;
  961. do {
  962. bytes = write(socket->sd, buffer + offset, length - offset);
  963. if(bytes <= 0) {
  964. if(bytes < 0)
  965. wi_error_set_errno(errno);
  966. else
  967. wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
  968. return bytes;
  969. }
  970. offset += bytes;
  971. if(offset < length) {
  972. wi_thread_sleep(0.1);
  973. if(timeout > 0.0) {
  974. interval += 0.1;
  975. if(interval >= timeout) {
  976. wi_error_set_errno(ETIMEDOUT);
  977. return -1;
  978. }
  979. }
  980. }
  981. } while(offset < length);
  982. return offset;
  983. #ifdef HAVE_OPENSSL_SSL_H
  984. }
  985. #endif
  986. return 0;
  987. }
  988. wi_string_t * wi_socket_read(wi_socket_t *socket, wi_time_interval_t timeout, size_t length) {
  989. wi_string_t *string;
  990. char buffer[WI_SOCKET_BUFFER_SIZE];
  991. int bytes = -1;
  992. string = wi_string_init_with_capacity(wi_string_alloc(), length);
  993. while(length > sizeof(buffer)) {
  994. bytes = wi_socket_read_buffer(socket, timeout, buffer, sizeof(buffer));
  995. if(bytes <= 0)
  996. goto end;
  997. wi_string_append_bytes(string, buffer, bytes);
  998. length -= bytes;
  999. }
  1000. if(length > 0) {
  1001. bytes = wi_socket_read_buffer(socket, timeout, buffer, length);
  1002. if(bytes <= 0)
  1003. goto end;
  1004. wi_string_append_bytes(string, buffer, bytes);
  1005. }
  1006. end:
  1007. if(wi_string_length(string) == 0) {
  1008. if(bytes < 0) {
  1009. wi_release(string);
  1010. string = NULL;
  1011. }
  1012. }
  1013. return wi_autorelease(string);
  1014. }
  1015. wi_string_t * wi_socket_read_to_string(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *separator) {
  1016. wi_string_t *string, *substring;
  1017. wi_uinteger_t index;
  1018. index = wi_string_index_of_string(socket->buffer, separator, 0);
  1019. if(index != WI_NOT_FOUND) {
  1020. substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
  1021. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  1022. return substring;
  1023. }
  1024. while((string = wi_socket_read(socket, timeout, WI_SOCKET_BUFFER_SIZE))) {
  1025. if(wi_string_length(string) == 0)
  1026. return string;
  1027. wi_string_append_string(socket->buffer, string);
  1028. index = wi_string_index_of_string(socket->buffer, separator, 0);
  1029. if(index == WI_NOT_FOUND) {
  1030. if(wi_string_length(socket->buffer) > _WI_SOCKET_BUFFER_MAX_SIZE) {
  1031. substring = wi_string_substring_to_index(socket->buffer, _WI_SOCKET_BUFFER_MAX_SIZE);
  1032. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  1033. return substring;
  1034. }
  1035. } else {
  1036. substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
  1037. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  1038. return substring;
  1039. }
  1040. }
  1041. return NULL;
  1042. }
  1043. wi_integer_t wi_socket_read_buffer(wi_socket_t *socket, wi_time_interval_t timeout, void *buffer, size_t length) {
  1044. wi_time_interval_t interval;
  1045. wi_socket_state_t state;
  1046. wi_uinteger_t offset;
  1047. wi_integer_t bytes;
  1048. WI_ASSERT(buffer != NULL, "buffer of length %u should not be NULL", length);
  1049. if(timeout > 0.0) {
  1050. #ifdef HAVE_OPENSSL_SSL_H
  1051. if(!socket->ssl || (socket->ssl && SSL_pending(socket->ssl) == 0)) {
  1052. #endif
  1053. state = wi_socket_wait_descriptor(socket->sd, timeout, true, false);
  1054. if(state != WI_SOCKET_READY) {
  1055. if(state == WI_SOCKET_TIMEOUT)
  1056. wi_error_set_errno(ETIMEDOUT);
  1057. return -1;
  1058. }
  1059. #ifdef HAVE_OPENSSL_SSL_H
  1060. }
  1061. #endif
  1062. }
  1063. interval = 0.0;
  1064. #ifdef HAVE_OPENSSL_SSL_H
  1065. if(socket->ssl) {
  1066. do {
  1067. bytes = SSL_read(socket->ssl, buffer, length);
  1068. if(bytes <= 0) {
  1069. if(bytes < 0 && SSL_get_error(socket->ssl, bytes) == SSL_ERROR_WANT_READ) {
  1070. wi_thread_sleep(0.1);
  1071. if(timeout > 0.0) {
  1072. interval += 0.1;
  1073. if(interval >= timeout) {
  1074. wi_error_set_errno(ETIMEDOUT);
  1075. break;
  1076. }
  1077. }
  1078. } else {
  1079. wi_error_set_openssl_ssl_error_with_result(socket->ssl, bytes);
  1080. socket->broken = true;
  1081. break;
  1082. }
  1083. }
  1084. } while(bytes <= 0);
  1085. return bytes;
  1086. } else {
  1087. #endif
  1088. offset = 0;
  1089. do {
  1090. bytes = read(socket->sd, buffer + offset, length - offset);
  1091. if(bytes <= 0) {
  1092. if(bytes < 0)
  1093. wi_error_set_errno(errno);
  1094. else
  1095. wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF);
  1096. return bytes;
  1097. }
  1098. offset += bytes;
  1099. if(offset < length) {
  1100. wi_thread_sleep(0.1);
  1101. if(timeout > 0.0) {
  1102. interval += 0.1;
  1103. if(interval >= timeout) {
  1104. wi_error_set_errno(ETIMEDOUT);
  1105. return -1;
  1106. }
  1107. }
  1108. }
  1109. } while(offset < length);
  1110. return offset;
  1111. #ifdef HAVE_OPENSSL_SSL_H
  1112. }
  1113. #endif
  1114. return 0;
  1115. }
  1116. #pragma mark -
  1117. wi_string_t * wi_socket_buffered_string(wi_socket_t *socket) {
  1118. return socket->buffer;
  1119. }