PageRenderTime 397ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/wired-1.3/libwired/libwired/net/wi-socket.c

https://bitbucket.org/balrog/zanka-full
C | 1490 lines | 969 code | 495 blank | 26 comment | 168 complexity | 21c8331bc83b99854b99b253b1371908 MD5 | raw file
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2003-2006 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. #include <netinet/in_systm.h>
  34. #include <netinet/ip.h>
  35. #include <netinet/tcp.h>
  36. #include <netdb.h>
  37. #include <net/if.h>
  38. #include <fcntl.h>
  39. #include <unistd.h>
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <errno.h>
  43. #ifdef WI_SSL
  44. #include <openssl/err.h>
  45. #include <openssl/ssl.h>
  46. #endif
  47. #ifdef HAVE_IFADDRS_H
  48. #include <ifaddrs.h>
  49. #endif
  50. #include <wired/wi-array.h>
  51. #include <wired/wi-assert.h>
  52. #include <wired/wi-address.h>
  53. #include <wired/wi-date.h>
  54. #include <wired/wi-macros.h>
  55. #include <wired/wi-list.h>
  56. #include <wired/wi-lock.h>
  57. #include <wired/wi-socket.h>
  58. #include <wired/wi-string.h>
  59. #include <wired/wi-system.h>
  60. #include <wired/wi-thread.h>
  61. #include "wi-private.h"
  62. #define _WI_SOCKET_BUFFER_MAX_SIZE 131072
  63. struct _wi_socket_context {
  64. wi_runtime_base_t base;
  65. #ifdef WI_SSL
  66. SSL_CTX *ssl_ctx;
  67. DH *dh;
  68. RSA *pub_rsa;
  69. RSA *priv_rsa;
  70. wi_boolean_t certificate;
  71. #endif
  72. };
  73. struct _wi_socket {
  74. wi_runtime_base_t base;
  75. wi_address_t *address;
  76. wi_socket_type_t type;
  77. uint32_t direction;
  78. int sd;
  79. #ifdef WI_SSL
  80. SSL *ssl;
  81. #endif
  82. void *data;
  83. wi_string_t *buffer;
  84. wi_boolean_t interactive;
  85. wi_boolean_t close;
  86. wi_boolean_t broken;
  87. };
  88. #if defined(WI_SSL) && defined(WI_PTHREADS)
  89. static unsigned long _wi_socket_ssl_id_function(void);
  90. static void _wi_socket_ssl_locking_function(int, int, const char *, int);
  91. #endif
  92. static void _wi_socket_context_dealloc(wi_runtime_instance_t *);
  93. static void _wi_socket_dealloc(wi_runtime_instance_t *);
  94. static wi_string_t * _wi_socket_description(wi_runtime_instance_t *);
  95. static wi_boolean_t _wi_socket_set_option(wi_socket_t *, int, int, int);
  96. static wi_boolean_t _wi_socket_get_option(wi_socket_t *, int, int, int *);
  97. #if defined(WI_SSL) && defined(WI_PTHREADS)
  98. static wi_array_t *_wi_socket_ssl_locks;
  99. #endif
  100. static wi_runtime_id_t _wi_socket_context_runtime_id = WI_RUNTIME_ID_NULL;
  101. static wi_runtime_class_t _wi_socket_context_runtime_class = {
  102. "wi_socket_context_t",
  103. _wi_socket_context_dealloc,
  104. NULL,
  105. NULL,
  106. NULL,
  107. NULL
  108. };
  109. static wi_runtime_id_t _wi_socket_runtime_id = WI_RUNTIME_ID_NULL;
  110. static wi_runtime_class_t _wi_socket_runtime_class = {
  111. "wi_socket_t",
  112. _wi_socket_dealloc,
  113. NULL,
  114. NULL,
  115. _wi_socket_description,
  116. NULL
  117. };
  118. void wi_socket_register(void) {
  119. _wi_socket_context_runtime_id = wi_runtime_register_class(&_wi_socket_context_runtime_class);
  120. _wi_socket_runtime_id = wi_runtime_register_class(&_wi_socket_runtime_class);
  121. }
  122. void wi_socket_initialize(void) {
  123. #ifdef WI_SSL
  124. #ifdef WI_PTHREADS
  125. wi_lock_t *lock;
  126. uint32_t i, count;
  127. #endif
  128. SSL_library_init();
  129. #ifdef WI_PTHREADS
  130. count = CRYPTO_num_locks();
  131. _wi_socket_ssl_locks = wi_array_init_with_capacity(wi_array_alloc(), count);
  132. for(i = 0; i < count; i++) {
  133. lock = wi_lock_init(wi_lock_alloc());
  134. wi_array_add_data(_wi_socket_ssl_locks, lock);
  135. wi_release(lock);
  136. }
  137. CRYPTO_set_id_callback(_wi_socket_ssl_id_function);
  138. CRYPTO_set_locking_callback(_wi_socket_ssl_locking_function);
  139. #endif
  140. #endif
  141. }
  142. #pragma mark -
  143. #if defined(WI_SSL) && defined(WI_PTHREADS)
  144. static unsigned long _wi_socket_ssl_id_function(void) {
  145. return ((unsigned long) wi_thread_current_thread());
  146. }
  147. static void _wi_socket_ssl_locking_function(int mode, int n, const char *file, int line) {
  148. wi_lock_t *lock;
  149. lock = WI_ARRAY(_wi_socket_ssl_locks, n);
  150. if(mode & CRYPTO_LOCK)
  151. wi_lock_lock(lock);
  152. else
  153. wi_lock_unlock(lock);
  154. }
  155. #endif
  156. #pragma mark -
  157. void wi_socket_exit_thread(void) {
  158. #ifdef WI_SSL
  159. ERR_remove_state(0);
  160. #endif
  161. }
  162. #pragma mark -
  163. wi_runtime_id_t wi_socket_context_runtime_id(void) {
  164. return _wi_socket_context_runtime_id;
  165. }
  166. #pragma mark -
  167. wi_socket_context_t * wi_socket_context_alloc(void) {
  168. return wi_runtime_create_instance(_wi_socket_context_runtime_id, sizeof(wi_socket_context_t));
  169. }
  170. wi_socket_context_t * wi_socket_context_init(wi_socket_context_t *context) {
  171. return context;
  172. }
  173. static void _wi_socket_context_dealloc(wi_runtime_instance_t *instance) {
  174. #ifdef WI_SSL
  175. wi_socket_context_t *context = instance;
  176. if(context->ssl_ctx)
  177. SSL_CTX_free(context->ssl_ctx);
  178. if(context->dh)
  179. DH_free(context->dh);
  180. #endif
  181. }
  182. #pragma mark -
  183. wi_boolean_t wi_socket_context_set_ssl_type(wi_socket_context_t *context, wi_socket_ssl_type_t type) {
  184. #ifdef WI_SSL
  185. SSL_METHOD *method = NULL;
  186. switch(type) {
  187. case WI_SOCKET_SSL_CLIENT:
  188. method = TLSv1_client_method();
  189. break;
  190. case WI_SOCKET_SSL_SERVER:
  191. method = TLSv1_server_method();
  192. break;
  193. }
  194. context->ssl_ctx = SSL_CTX_new(method);
  195. if(!context->ssl_ctx)
  196. wi_error_set_ssl_error();
  197. return (context->ssl_ctx != NULL);
  198. #else
  199. wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
  200. return false;
  201. #endif
  202. }
  203. wi_boolean_t wi_socket_context_set_ssl_certificate(wi_socket_context_t *context, wi_string_t *path) {
  204. #ifdef WI_SSL
  205. const char *certificate;
  206. context->certificate = false;
  207. certificate = wi_string_cstring(path);
  208. if(SSL_CTX_use_certificate_chain_file(context->ssl_ctx, certificate) != 1) {
  209. wi_error_set_ssl_error();
  210. return false;
  211. }
  212. if(SSL_CTX_use_PrivateKey_file(context->ssl_ctx, certificate, SSL_FILETYPE_PEM) != 1) {
  213. wi_error_set_ssl_error();
  214. return false;
  215. }
  216. context->certificate = true;
  217. return true;
  218. #else
  219. wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
  220. return false;
  221. #endif
  222. }
  223. wi_boolean_t wi_socket_context_set_ssl_privkey(wi_socket_context_t *context, wi_string_t *path) {
  224. #ifdef WI_SSL
  225. FILE *fp;
  226. fp = fopen(wi_string_cstring(path), "r");
  227. if(!fp) {
  228. wi_error_set_errno(errno);
  229. return false;
  230. }
  231. context->priv_rsa = PEM_read_RSAPrivateKey(fp, NULL, 0, NULL);
  232. if(!context->priv_rsa)
  233. wi_error_set_ssl_error();
  234. fclose(fp);
  235. return (context->priv_rsa != NULL);
  236. #else
  237. wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
  238. return false;
  239. #endif
  240. }
  241. void wi_socket_context_set_ssl_pubkey(wi_socket_context_t *context, void *rsa) {
  242. #ifdef WI_SSL
  243. if(context->pub_rsa != rsa) {
  244. if(context->pub_rsa)
  245. RSA_free(context->pub_rsa);
  246. context->pub_rsa = rsa;
  247. }
  248. #endif
  249. }
  250. wi_boolean_t wi_socket_context_set_ssl_ciphers(wi_socket_context_t *context, wi_string_t *ciphers) {
  251. #ifdef WI_SSL
  252. if(SSL_CTX_set_cipher_list(context->ssl_ctx, wi_string_cstring(ciphers)) != 1) {
  253. wi_error_set_lib_error(WI_ERROR_SOCKET_NOVALIDCIPHER);
  254. return false;
  255. }
  256. return true;
  257. #else
  258. wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
  259. return false;
  260. #endif
  261. }
  262. wi_boolean_t wi_socket_context_set_ssl_dh(wi_socket_context_t *context, const unsigned char *p, size_t p_size, const unsigned char *g, size_t g_size) {
  263. #ifdef WI_SSL
  264. context->dh = DH_new();
  265. if(!context->dh) {
  266. wi_error_set_ssl_error();
  267. return false;
  268. }
  269. context->dh->p = BN_bin2bn(p, p_size, NULL);
  270. context->dh->g = BN_bin2bn(g, g_size, NULL);
  271. if(!context->dh->p || !context->dh->g) {
  272. wi_error_set_ssl_error();
  273. DH_free(context->dh);
  274. context->dh = NULL;
  275. return false;
  276. }
  277. return true;
  278. #else
  279. wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
  280. return false;
  281. #endif
  282. }
  283. #pragma mark -
  284. wi_runtime_id_t wi_socket_runtime_id(void) {
  285. return _wi_socket_runtime_id;
  286. }
  287. #pragma mark -
  288. wi_socket_t * wi_socket_alloc(void) {
  289. return wi_runtime_create_instance(_wi_socket_runtime_id, sizeof(wi_socket_t));
  290. }
  291. wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) {
  292. _socket->address = wi_copy(address);
  293. _socket->close = true;
  294. _socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
  295. _socket->type = type;
  296. _socket->sd = socket(wi_address_family(_socket->address), _socket->type, 0);
  297. if(_socket->sd < 0) {
  298. wi_error_set_errno(errno);
  299. wi_release(_socket);
  300. return NULL;
  301. }
  302. if(!_wi_socket_set_option(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
  303. wi_release(_socket);
  304. return NULL;
  305. }
  306. return _socket;
  307. }
  308. wi_socket_t * wi_socket_init_with_descriptor(wi_socket_t *socket, int sd) {
  309. socket->sd = sd;
  310. socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
  311. return socket;
  312. }
  313. static void _wi_socket_dealloc(wi_runtime_instance_t *instance) {
  314. wi_socket_t *socket = instance;
  315. wi_socket_close(socket);
  316. wi_release(socket->address);
  317. wi_release(socket->buffer);
  318. }
  319. static wi_string_t * _wi_socket_description(wi_runtime_instance_t *instance) {
  320. wi_socket_t *socket = instance;
  321. return wi_string_with_format(WI_STR("<%s %p>{sd = %d, address = %@}"),
  322. wi_runtime_class_name(socket),
  323. socket,
  324. socket->sd,
  325. socket->address);
  326. }
  327. #pragma mark -
  328. static wi_boolean_t _wi_socket_set_option(wi_socket_t *socket, int level, int name, int option) {
  329. if(setsockopt(socket->sd, level, name, &option, sizeof(option)) < 0) {
  330. wi_error_set_errno(errno);
  331. return false;
  332. }
  333. return true;
  334. }
  335. static wi_boolean_t _wi_socket_get_option(wi_socket_t *socket, int level, int name, int *option) {
  336. socklen_t length;
  337. length = sizeof(*option);
  338. if(getsockopt(socket->sd, level, name, option, &length) < 0) {
  339. wi_error_set_errno(errno);
  340. *option = 0;
  341. return false;
  342. }
  343. return true;
  344. }
  345. #pragma mark -
  346. wi_address_t * wi_socket_address(wi_socket_t *socket) {
  347. return socket->address;
  348. }
  349. int wi_socket_descriptor(wi_socket_t *socket) {
  350. return socket->sd;
  351. }
  352. void * wi_socket_ssl(wi_socket_t *socket) {
  353. #ifdef WI_SSL
  354. return socket->ssl;
  355. #else
  356. return NULL;
  357. #endif
  358. }
  359. void * wi_socket_ssl_pubkey(wi_socket_t *socket) {
  360. #ifdef WI_SSL
  361. RSA *rsa = NULL;
  362. X509 *x509 = NULL;
  363. EVP_PKEY *pkey = NULL;
  364. x509 = SSL_get_peer_certificate(socket->ssl);
  365. if(!x509) {
  366. wi_error_set_ssl_error();
  367. goto end;
  368. }
  369. pkey = X509_get_pubkey(x509);
  370. if(!pkey) {
  371. wi_error_set_ssl_error();
  372. goto end;
  373. }
  374. rsa = EVP_PKEY_get1_RSA(pkey);
  375. if(!rsa)
  376. wi_error_set_ssl_error();
  377. end:
  378. if(x509)
  379. X509_free(x509);
  380. if(pkey)
  381. EVP_PKEY_free(pkey);
  382. return rsa;
  383. #else
  384. return NULL;
  385. #endif
  386. }
  387. wi_string_t * wi_socket_cipher_version(wi_socket_t *socket) {
  388. #ifdef WI_SSL
  389. return wi_string_with_cstring(SSL_get_cipher_version(socket->ssl));
  390. #else
  391. return NULL;
  392. #endif
  393. }
  394. wi_string_t * wi_socket_cipher_name(wi_socket_t *socket) {
  395. #ifdef WI_SSL
  396. return wi_string_with_cstring(SSL_get_cipher_name(socket->ssl));
  397. #else
  398. return NULL;
  399. #endif
  400. }
  401. uint32_t wi_socket_cipher_bits(wi_socket_t *socket) {
  402. #ifdef WI_SSL
  403. return SSL_get_cipher_bits(socket->ssl, NULL);
  404. #else
  405. return 0;
  406. #endif
  407. }
  408. wi_string_t * wi_socket_certificate_name(wi_socket_t *socket) {
  409. #ifdef WI_SSL
  410. X509 *x509 = NULL;
  411. EVP_PKEY *pkey = NULL;
  412. wi_string_t *string = NULL;
  413. x509 = SSL_get_peer_certificate(socket->ssl);
  414. if(!x509)
  415. goto end;
  416. pkey = X509_get_pubkey(x509);
  417. if(!pkey)
  418. goto end;
  419. switch(EVP_PKEY_type(pkey->type)) {
  420. case EVP_PKEY_RSA:
  421. string = wi_string_init_with_cstring(wi_string_alloc(), "RSA");
  422. break;
  423. case EVP_PKEY_DSA:
  424. string = wi_string_init_with_cstring(wi_string_alloc(), "DSA");
  425. break;
  426. case EVP_PKEY_DH:
  427. string = wi_string_init_with_cstring(wi_string_alloc(), "DH");
  428. break;
  429. default:
  430. break;
  431. }
  432. end:
  433. if(x509)
  434. X509_free(x509);
  435. if(pkey)
  436. EVP_PKEY_free(pkey);
  437. return wi_autorelease(string);
  438. #else
  439. return NULL;
  440. #endif
  441. }
  442. uint32_t wi_socket_certificate_bits(wi_socket_t *socket) {
  443. #ifdef WI_SSL
  444. X509 *x509 = NULL;
  445. EVP_PKEY *pkey = NULL;
  446. uint32_t bits = 0;
  447. x509 = SSL_get_peer_certificate(socket->ssl);
  448. if(!x509)
  449. goto end;
  450. pkey = X509_get_pubkey(x509);
  451. if(!pkey)
  452. goto end;
  453. bits = 8 * EVP_PKEY_size(pkey);
  454. end:
  455. if(x509)
  456. X509_free(x509);
  457. if(pkey)
  458. EVP_PKEY_free(pkey);
  459. return bits;
  460. #else
  461. return 0;
  462. #endif
  463. }
  464. wi_string_t * wi_socket_certificate_hostname(wi_socket_t *socket) {
  465. #ifdef WI_SSL
  466. X509 *x509;
  467. wi_string_t *string;
  468. char hostname[MAXHOSTNAMELEN];
  469. x509 = SSL_get_peer_certificate(socket->ssl);
  470. if(!x509)
  471. return NULL;
  472. X509_NAME_get_text_by_NID(X509_get_subject_name(x509),
  473. NID_commonName,
  474. hostname,
  475. sizeof(hostname));
  476. string = wi_string_init_with_cstring(wi_string_alloc(), hostname);
  477. X509_free(x509);
  478. return wi_autorelease(string);
  479. #else
  480. return NULL;
  481. #endif
  482. }
  483. #pragma mark -
  484. void wi_socket_set_port(wi_socket_t *socket, uint32_t port) {
  485. wi_address_set_port(socket->address, port);
  486. }
  487. uint32_t wi_socket_port(wi_socket_t *socket) {
  488. return wi_address_port(socket->address);
  489. }
  490. void wi_socket_set_direction(wi_socket_t *socket, uint32_t direction) {
  491. socket->direction = direction;
  492. }
  493. uint32_t wi_socket_direction(wi_socket_t *socket) {
  494. return socket->direction;
  495. }
  496. void wi_socket_set_data(wi_socket_t *socket, void *data) {
  497. socket->data = data;
  498. }
  499. void * wi_socket_data(wi_socket_t *socket) {
  500. return socket->data;
  501. }
  502. void wi_socket_set_blocking(wi_socket_t *socket, wi_boolean_t blocking) {
  503. int flags;
  504. flags = fcntl(socket->sd, F_GETFL);
  505. if(flags < 0) {
  506. wi_error_set_errno(errno);
  507. return;
  508. }
  509. if(blocking)
  510. flags &= ~O_NONBLOCK;
  511. else
  512. flags |= O_NONBLOCK;
  513. if(fcntl(socket->sd, F_SETFL, flags) < 0) {
  514. wi_error_set_errno(errno);
  515. return;
  516. }
  517. }
  518. wi_boolean_t wi_socket_blocking(wi_socket_t *socket) {
  519. int flags;
  520. flags = fcntl(socket->sd, F_GETFL);
  521. if(flags < 0) {
  522. wi_error_set_errno(errno);
  523. return false;
  524. }
  525. return !(flags & O_NONBLOCK);
  526. }
  527. void wi_socket_set_interactive(wi_socket_t *socket, wi_boolean_t interactive) {
  528. if(socket->type == WI_SOCKET_TCP && interactive)
  529. _wi_socket_set_option(socket, IPPROTO_TCP, TCP_NODELAY, 1);
  530. if(wi_address_family(socket->address) == WI_ADDRESS_IPV4)
  531. _wi_socket_set_option(socket, IPPROTO_IP, IP_TOS, interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT);
  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(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_list_t *list, wi_time_interval_t timeout) {
  546. wi_list_node_t *node;
  547. wi_socket_t *socket, *accept_socket;
  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_list_rdlock(list);
  556. WI_LIST_FOREACH(list, node, socket) {
  557. if(socket->direction & WI_SOCKET_READ)
  558. FD_SET(socket->sd, &rfds);
  559. if(socket->direction & WI_SOCKET_WRITE)
  560. FD_SET(socket->sd, &wfds);
  561. if(socket->sd > max_sd)
  562. max_sd = socket->sd;
  563. }
  564. wi_list_unlock(list);
  565. state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
  566. if(state < 0) {
  567. wi_error_set_errno(errno);
  568. return NULL;
  569. }
  570. accept_socket = NULL;
  571. wi_list_rdlock(list);
  572. WI_LIST_FOREACH(list, node, socket) {
  573. if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) {
  574. accept_socket = socket;
  575. break;
  576. }
  577. }
  578. wi_list_unlock(list);
  579. return accept_socket;
  580. }
  581. wi_boolean_t wi_socket_wait(wi_socket_t *socket, wi_time_interval_t timeout) {
  582. return wi_socket_wait_descriptor(socket->sd,
  583. timeout,
  584. (socket->direction & WI_SOCKET_READ),
  585. (socket->direction & WI_SOCKET_WRITE));
  586. }
  587. wi_boolean_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
  588. struct timeval tv;
  589. fd_set rfds, wfds;
  590. int state;
  591. tv = wi_dtotv(timeout);
  592. FD_ZERO(&rfds);
  593. FD_ZERO(&wfds);
  594. if(read)
  595. FD_SET(sd, &rfds);
  596. if(write)
  597. FD_SET(sd, &wfds);
  598. state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
  599. if(state < 0)
  600. wi_error_set_errno(errno);
  601. else if(state == 0)
  602. wi_error_set_errno(ETIMEDOUT);
  603. return (state > 0);
  604. }
  605. #pragma mark -
  606. wi_boolean_t wi_socket_listen(wi_socket_t *_socket, uint32_t backlog) {
  607. struct sockaddr *sa;
  608. uint32_t length;
  609. sa = wi_address_sa(_socket->address);
  610. length = wi_address_sa_length(_socket->address);
  611. if(bind(_socket->sd, sa, length) < 0) {
  612. wi_error_set_errno(errno);
  613. return false;
  614. }
  615. if(_socket->type == WI_SOCKET_TCP) {
  616. if(listen(_socket->sd, backlog) < 0) {
  617. wi_error_set_errno(errno);
  618. return false;
  619. }
  620. }
  621. _socket->direction = WI_SOCKET_READ;
  622. return true;
  623. }
  624. wi_boolean_t wi_socket_connect(wi_socket_t *socket, wi_socket_context_t *context, wi_time_interval_t timeout) {
  625. struct sockaddr *sa;
  626. uint32_t length;
  627. int state, err;
  628. #ifdef WI_SSL
  629. int ret;
  630. #endif
  631. wi_boolean_t blocking;
  632. blocking = wi_socket_blocking(socket);
  633. if(blocking)
  634. wi_socket_set_blocking(socket, false);
  635. sa = wi_address_sa(socket->address);
  636. length = wi_address_sa_length(socket->address);
  637. err = connect(socket->sd, sa, length);
  638. if(err < 0) {
  639. if(errno != EINPROGRESS) {
  640. wi_error_set_errno(errno);
  641. return false;
  642. }
  643. do {
  644. state = wi_socket_wait_descriptor(socket->sd, 1.0, true, true);
  645. timeout -= 1.0;
  646. } while(state == 0 && timeout >= 0.0);
  647. if(state < 0)
  648. return false;
  649. if(timeout <= 0.0) {
  650. wi_error_set_errno(ETIMEDOUT);
  651. return false;
  652. }
  653. err = wi_socket_error(socket);
  654. if(err != 0) {
  655. wi_error_set_errno(err);
  656. return false;
  657. }
  658. }
  659. #ifdef WI_SSL
  660. if(context && context->ssl_ctx) {
  661. socket->ssl = SSL_new(context->ssl_ctx);
  662. if(!socket->ssl) {
  663. wi_error_set_ssl_error();
  664. return false;
  665. }
  666. if(SSL_set_fd(socket->ssl, socket->sd) != 1) {
  667. wi_error_set_ssl_error();
  668. return false;
  669. }
  670. ret = SSL_connect(socket->ssl);
  671. if(ret != 1) {
  672. do {
  673. err = SSL_get_error(socket->ssl, ret);
  674. if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
  675. wi_error_set_ssl_error();
  676. return false;
  677. }
  678. state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE));
  679. if(state < 0)
  680. break;
  681. if(state > 0) {
  682. ret = SSL_connect(socket->ssl);
  683. if(ret == 1)
  684. break;
  685. }
  686. timeout -= 1.0;
  687. } while(timeout >= 0.0);
  688. if(state < 0)
  689. return false;
  690. if(timeout <= 0.0) {
  691. wi_error_set_errno(ETIMEDOUT);
  692. return false;
  693. }
  694. }
  695. }
  696. #endif
  697. if(blocking)
  698. wi_socket_set_blocking(socket, true);
  699. socket->direction = WI_SOCKET_READ;
  700. return true;
  701. }
  702. wi_socket_t * wi_socket_accept_multiple(wi_list_t *list, wi_socket_context_t *context, wi_time_interval_t timeout, wi_address_t **address) {
  703. wi_socket_t *socket;
  704. *address = NULL;
  705. socket = wi_socket_wait_multiple(list, 0.0);
  706. if(!socket)
  707. return NULL;
  708. return wi_socket_accept(socket, context, timeout, address);
  709. }
  710. wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_socket_context_t *context, wi_time_interval_t timeout, wi_address_t **address) {
  711. wi_socket_t *socket;
  712. #ifdef WI_SSL
  713. SSL *ssl = NULL;
  714. #endif
  715. struct sockaddr_storage ss;
  716. socklen_t length;
  717. int sd;
  718. length = sizeof(ss);
  719. sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length);
  720. *address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
  721. if(sd < 0) {
  722. wi_error_set_errno(errno);
  723. goto err;
  724. }
  725. #ifdef WI_SSL
  726. if(context && context->ssl_ctx) {
  727. ssl = SSL_new(context->ssl_ctx);
  728. if(!ssl) {
  729. wi_error_set_ssl_error();
  730. goto err;
  731. }
  732. if(SSL_set_fd(ssl, sd) != 1) {
  733. wi_error_set_ssl_error();
  734. goto err;
  735. }
  736. if(!context->certificate && context->dh) {
  737. if(SSL_set_tmp_dh(ssl, context->dh) != 1) {
  738. wi_error_set_ssl_error();
  739. goto err;
  740. }
  741. }
  742. if(timeout > 0.0) {
  743. if(wi_socket_wait_descriptor(sd, timeout, true, false) <= 0)
  744. goto err;
  745. }
  746. if(SSL_accept(ssl) != 1) {
  747. wi_error_set_ssl_error();
  748. goto err;
  749. }
  750. }
  751. #endif
  752. socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd);
  753. socket->close = true;
  754. socket->address = wi_retain(*address);
  755. socket->type = accept_socket->type;
  756. socket->direction = WI_SOCKET_READ;
  757. socket->interactive = accept_socket->interactive;
  758. #ifdef WI_SSL
  759. socket->ssl = ssl;
  760. #endif
  761. return wi_autorelease(socket);
  762. err:
  763. #ifdef WI_SSL
  764. if(ssl)
  765. SSL_free(ssl);
  766. #endif
  767. if(sd >= 0)
  768. close(sd);
  769. return NULL;
  770. }
  771. void wi_socket_close(wi_socket_t *socket) {
  772. #ifdef WI_SSL
  773. if(socket->ssl) {
  774. if(!socket->broken) {
  775. if(SSL_shutdown(socket->ssl) == 0)
  776. SSL_shutdown(socket->ssl);
  777. }
  778. SSL_free(socket->ssl);
  779. socket->ssl = NULL;
  780. }
  781. #endif
  782. if(socket->close && socket->sd >= 0) {
  783. close(socket->sd);
  784. socket->sd = -1;
  785. }
  786. }
  787. #pragma mark -
  788. int32_t wi_socket_sendto(wi_socket_t *socket, wi_socket_context_t *context, wi_string_t *fmt, ...) {
  789. wi_string_t *string;
  790. int bytes;
  791. va_list ap;
  792. va_start(ap, fmt);
  793. string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
  794. va_end(ap);
  795. bytes = wi_socket_sendto_buffer(socket, context, wi_string_cstring(string), wi_string_length(string));
  796. wi_release(string);
  797. return bytes;
  798. }
  799. int32_t wi_socket_sendto_buffer(wi_socket_t *socket, wi_socket_context_t *context, const char *buffer, size_t length) {
  800. wi_address_t *address;
  801. char *outbuffer = NULL;
  802. int bytes;
  803. address = wi_socket_address(socket);
  804. #ifdef WI_SSL
  805. if(context && context->pub_rsa) {
  806. outbuffer = wi_malloc(RSA_size(context->pub_rsa));
  807. bytes = RSA_public_encrypt(length, (unsigned char *) buffer, (unsigned char *) outbuffer,
  808. context->pub_rsa, RSA_PKCS1_OAEP_PADDING);
  809. if(bytes < 0) {
  810. wi_error_set_ssl_error();
  811. goto end;
  812. }
  813. bytes = sendto(socket->sd, outbuffer, bytes, 0,
  814. wi_address_sa(address), wi_address_sa_length(address));
  815. } else {
  816. #endif
  817. bytes = sendto(socket->sd, buffer, length, 0,
  818. wi_address_sa(address), wi_address_sa_length(address));
  819. #ifdef WI_SSL
  820. }
  821. #endif
  822. if(bytes < 0) {
  823. wi_error_set_errno(errno);
  824. goto end;
  825. }
  826. end:
  827. if(outbuffer)
  828. wi_free(outbuffer);
  829. return bytes;
  830. }
  831. int32_t wi_socket_recvfrom_multiple(wi_list_t *list, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) {
  832. wi_socket_t *socket;
  833. *address = NULL;
  834. socket = wi_socket_wait_multiple(list, 0.0);
  835. if(!socket)
  836. return -1;
  837. return wi_socket_recvfrom(socket, context, buffer, length, address);
  838. }
  839. int32_t wi_socket_recvfrom(wi_socket_t *socket, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) {
  840. struct sockaddr_storage ss;
  841. char *inbuffer = NULL;
  842. socklen_t sslength;
  843. int bytes;
  844. sslength = sizeof(ss);
  845. #ifdef WI_SSL
  846. if(context && context->priv_rsa) {
  847. inbuffer = wi_malloc(length);
  848. bytes = recvfrom(socket->sd, inbuffer, length, 0, (struct sockaddr *) &ss, &sslength);
  849. if(bytes < 0) {
  850. wi_error_set_errno(errno);
  851. goto end;
  852. }
  853. bytes = RSA_private_decrypt(bytes, (unsigned char *) inbuffer, (unsigned char *) buffer,
  854. context->priv_rsa, RSA_PKCS1_OAEP_PADDING);
  855. if(bytes < 0) {
  856. wi_error_set_ssl_error();
  857. goto end;
  858. }
  859. } else {
  860. #endif
  861. bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength);
  862. if(bytes < 0) {
  863. wi_error_set_errno(errno);
  864. goto end;
  865. }
  866. #ifdef WI_SSL
  867. }
  868. #endif
  869. end:
  870. *address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
  871. if(inbuffer)
  872. wi_free(inbuffer);
  873. return bytes;
  874. }
  875. #pragma mark -
  876. int32_t wi_socket_write(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *fmt, ...) {
  877. wi_string_t *string;
  878. int bytes;
  879. va_list ap;
  880. va_start(ap, fmt);
  881. string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
  882. va_end(ap);
  883. bytes = wi_socket_write_buffer(socket, timeout, wi_string_cstring(string), wi_string_length(string));
  884. wi_release(string);
  885. return bytes;
  886. }
  887. int32_t wi_socket_write_buffer(wi_socket_t *socket, wi_time_interval_t timeout, const void *buffer, size_t length) {
  888. int bytes;
  889. if(timeout > 0.0) {
  890. if(wi_socket_wait_descriptor(socket->sd, timeout, false, true) <= 0)
  891. return -1;
  892. }
  893. #ifdef WI_SSL
  894. if(socket->ssl) {
  895. bytes = SSL_write(socket->ssl, buffer, length);
  896. if(bytes < 0) {
  897. wi_error_set_ssl_error();
  898. socket->broken = true;
  899. }
  900. } else {
  901. #endif
  902. bytes = write(socket->sd, buffer, length);
  903. if(bytes < 0)
  904. wi_error_set_errno(errno);
  905. #ifdef WI_SSL
  906. }
  907. #endif
  908. return bytes;
  909. }
  910. wi_string_t * wi_socket_read(wi_socket_t *socket, wi_time_interval_t timeout, size_t length) {
  911. wi_string_t *string;
  912. char buffer[WI_SOCKET_BUFFER_SIZE];
  913. int bytes = -1;
  914. string = wi_string_init_with_capacity(wi_string_alloc(), length);
  915. while(length > sizeof(buffer)) {
  916. bytes = wi_socket_read_buffer(socket, timeout, buffer, sizeof(buffer));
  917. if(bytes <= 0)
  918. goto end;
  919. wi_string_append_bytes(string, buffer, bytes);
  920. length -= bytes;
  921. }
  922. if(length > 0) {
  923. bytes = wi_socket_read_buffer(socket, timeout, buffer, length);
  924. if(bytes <= 0)
  925. goto end;
  926. wi_string_append_bytes(string, buffer, bytes);
  927. }
  928. end:
  929. if(wi_string_length(string) == 0) {
  930. if(bytes < 0) {
  931. wi_release(string);
  932. string = NULL;
  933. }
  934. }
  935. return wi_autorelease(string);
  936. }
  937. wi_string_t * wi_socket_read_to_string(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *separator) {
  938. wi_string_t *string, *substring;
  939. uint32_t index;
  940. index = wi_string_index_of_string(socket->buffer, separator, 0);
  941. if(index != WI_NOT_FOUND) {
  942. substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
  943. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  944. return substring;
  945. }
  946. while((string = wi_socket_read(socket, timeout, WI_SOCKET_BUFFER_SIZE))) {
  947. if(wi_string_length(string) == 0)
  948. return string;
  949. wi_string_append_string(socket->buffer, string);
  950. index = wi_string_index_of_string(socket->buffer, separator, 0);
  951. if(index == WI_NOT_FOUND) {
  952. if(wi_string_length(socket->buffer) > _WI_SOCKET_BUFFER_MAX_SIZE) {
  953. substring = wi_string_substring_to_index(socket->buffer, _WI_SOCKET_BUFFER_MAX_SIZE);
  954. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  955. return substring;
  956. }
  957. } else {
  958. substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
  959. wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
  960. return substring;
  961. }
  962. }
  963. return NULL;
  964. }
  965. int32_t wi_socket_read_buffer(wi_socket_t *socket, wi_time_interval_t timeout, void *buffer, size_t length) {
  966. int bytes;
  967. if(timeout > 0.0) {
  968. #ifdef WI_SSL
  969. if(socket->ssl && SSL_pending(socket->ssl) == 0) {
  970. #endif
  971. if(wi_socket_wait_descriptor(socket->sd, timeout, true, false) <= 0)
  972. return -1;
  973. #ifdef WI_SSL
  974. }
  975. #endif
  976. }
  977. #ifdef WI_SSL
  978. if(socket->ssl) {
  979. bytes = SSL_read(socket->ssl, buffer, length);
  980. if(bytes <= 0) {
  981. wi_error_set_ssl_error();
  982. socket->broken = true;
  983. }
  984. } else {
  985. #endif
  986. bytes = read(socket->sd, buffer, length);
  987. if(bytes < 0)
  988. wi_error_set_errno(errno);
  989. else if(bytes == 0)
  990. wi_error_set_lib_error(WI_ERROR_SOCKET_EOF);
  991. #ifdef WI_SSL
  992. }
  993. #endif
  994. return bytes;
  995. }