PageRenderTime 392ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

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

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