/tags/Footagehead-1.3.2/libwired/libwired/net/wi-socket.c
C | 1696 lines | 1093 code | 577 blank | 26 comment | 215 complexity | 116f45e6588c23e69ca7ac7b90b31f5c MD5 | raw file
1/* $Id$ */ 2 3/* 4 * Copyright (c) 2003-2009 Axel Andersson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "config.h" 30 31#include <sys/param.h> 32#include <sys/types.h> 33#include <sys/time.h> 34#include <sys/socket.h> 35#include <netinet/in.h> 36 37#ifdef HAVE_NETINET_IN_SYSTM_H 38#include <netinet/in_systm.h> 39#endif 40 41#ifdef HAVE_NETINET_IP_H 42#include <netinet/ip.h> 43#endif 44 45#include <netinet/tcp.h> 46#include <netdb.h> 47#include <net/if.h> 48#include <fcntl.h> 49#include <unistd.h> 50#include <stdio.h> 51#include <string.h> 52#include <errno.h> 53 54#ifdef HAVE_OPENSSL_SSL_H 55#include <openssl/err.h> 56#include <openssl/ssl.h> 57#endif 58 59#ifdef HAVE_IFADDRS_H 60#include <ifaddrs.h> 61#endif 62 63#include <wired/wi-array.h> 64#include <wired/wi-assert.h> 65#include <wired/wi-address.h> 66#include <wired/wi-date.h> 67#include <wired/wi-macros.h> 68#include <wired/wi-lock.h> 69#include <wired/wi-private.h> 70#include <wired/wi-rsa.h> 71#include <wired/wi-socket.h> 72#include <wired/wi-string.h> 73#include <wired/wi-system.h> 74#include <wired/wi-thread.h> 75#include <wired/wi-x509.h> 76 77#define _WI_SOCKET_BUFFER_MAX_SIZE 131072 78 79 80struct _wi_socket_tls { 81 wi_runtime_base_t base; 82 83#ifdef HAVE_OPENSSL_SSL_H 84 SSL_CTX *ssl_ctx; 85 DH *dh; 86 wi_boolean_t private_key; 87#endif 88}; 89 90 91struct _wi_socket { 92 wi_runtime_base_t base; 93 94 wi_address_t *address; 95 wi_socket_type_t type; 96 wi_uinteger_t direction; 97 int sd; 98 99#ifdef HAVE_OPENSSL_SSL_H 100 SSL *ssl; 101#endif 102 103 void *data; 104 105 wi_string_t *buffer; 106 107 wi_boolean_t interactive; 108 wi_boolean_t close; 109 wi_boolean_t broken; 110}; 111 112 113#if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS) 114static unsigned long _wi_socket_ssl_id_function(void); 115static void _wi_socket_ssl_locking_function(int, int, const char *, int); 116#endif 117 118#ifdef HAVE_OPENSSL_SSL_H 119static void _wi_socket_tls_dealloc(wi_runtime_instance_t *); 120#endif 121 122static void _wi_socket_dealloc(wi_runtime_instance_t *); 123static wi_string_t * _wi_socket_description(wi_runtime_instance_t *); 124 125static wi_boolean_t _wi_socket_set_option_int(wi_socket_t *, int, int, int); 126static wi_boolean_t _wi_socket_get_option_int(wi_socket_t *, int, int, int *); 127 128 129#if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS) 130static wi_array_t *_wi_socket_ssl_locks; 131#endif 132 133#ifdef HAVE_OPENSSL_SSL_H 134 135static wi_runtime_id_t _wi_socket_tls_runtime_id = WI_RUNTIME_ID_NULL; 136static wi_runtime_class_t _wi_socket_tls_runtime_class = { 137 "wi_socket_tls_t", 138 _wi_socket_tls_dealloc, 139 NULL, 140 NULL, 141 NULL, 142 NULL 143}; 144 145#endif 146 147static wi_runtime_id_t _wi_socket_runtime_id = WI_RUNTIME_ID_NULL; 148static wi_runtime_class_t _wi_socket_runtime_class = { 149 "wi_socket_t", 150 _wi_socket_dealloc, 151 NULL, 152 NULL, 153 _wi_socket_description, 154 NULL 155}; 156 157 158 159void wi_socket_register(void) { 160#ifdef HAVE_OPENSSL_SSL_H 161 _wi_socket_tls_runtime_id = wi_runtime_register_class(&_wi_socket_tls_runtime_class); 162#endif 163 164 _wi_socket_runtime_id = wi_runtime_register_class(&_wi_socket_runtime_class); 165} 166 167 168 169void wi_socket_initialize(void) { 170#ifdef HAVE_OPENSSL_SSL_H 171#ifdef WI_PTHREADS 172 wi_lock_t *lock; 173 wi_uinteger_t i, count; 174#endif 175 176 SSL_library_init(); 177 178#ifdef WI_PTHREADS 179 count = CRYPTO_num_locks(); 180 _wi_socket_ssl_locks = wi_array_init_with_capacity(wi_array_alloc(), count); 181 182 for(i = 0; i < count; i++) { 183 lock = wi_lock_init(wi_lock_alloc()); 184 wi_array_add_data(_wi_socket_ssl_locks, lock); 185 wi_release(lock); 186 } 187 188 CRYPTO_set_id_callback(_wi_socket_ssl_id_function); 189 CRYPTO_set_locking_callback(_wi_socket_ssl_locking_function); 190#endif 191#endif 192} 193 194 195 196#pragma mark - 197 198#if defined(HAVE_OPENSSL_SSL_H) && defined(WI_PTHREADS) 199 200static unsigned long _wi_socket_ssl_id_function(void) { 201 return ((unsigned long) wi_thread_current_thread()); 202} 203 204 205 206static void _wi_socket_ssl_locking_function(int mode, int n, const char *file, int line) { 207 wi_lock_t *lock; 208 209 lock = WI_ARRAY(_wi_socket_ssl_locks, n); 210 211 if(mode & CRYPTO_LOCK) 212 wi_lock_lock(lock); 213 else 214 wi_lock_unlock(lock); 215} 216 217#endif 218 219 220 221#pragma mark - 222 223void wi_socket_exit_thread(void) { 224#ifdef HAVE_OPENSSL_SSL_H 225 ERR_remove_state(0); 226#endif 227} 228 229 230 231#pragma mark - 232 233#ifdef HAVE_OPENSSL_SSL_H 234 235wi_runtime_id_t wi_socket_tls_runtime_id(void) { 236 return _wi_socket_tls_runtime_id; 237} 238 239 240 241#pragma mark - 242 243wi_socket_tls_t * wi_socket_tls_alloc(void) { 244 return wi_runtime_create_instance(_wi_socket_tls_runtime_id, sizeof(wi_socket_tls_t)); 245} 246 247 248 249wi_socket_tls_t * wi_socket_tls_init_with_type(wi_socket_tls_t *tls, wi_socket_tls_type_t type) { 250 SSL_METHOD *method; 251 252 switch(type) { 253 default: 254 case WI_SOCKET_TLS_CLIENT: 255 method = TLSv1_client_method(); 256 break; 257 258 case WI_SOCKET_TLS_SERVER: 259 method = TLSv1_server_method(); 260 break; 261 } 262 263 tls->ssl_ctx = SSL_CTX_new(method); 264 265 if(!tls->ssl_ctx) { 266 wi_error_set_openssl_error(); 267 268 wi_release(NULL); 269 270 return NULL; 271 } 272 273 SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY); 274 SSL_CTX_set_quiet_shutdown(tls->ssl_ctx, 1); 275 276 return tls; 277} 278 279 280 281static void _wi_socket_tls_dealloc(wi_runtime_instance_t *instance) { 282 wi_socket_tls_t *tls = instance; 283 284 if(tls->ssl_ctx) 285 SSL_CTX_free(tls->ssl_ctx); 286 287 if(tls->dh) 288 DH_free(tls->dh); 289} 290 291 292 293#pragma mark - 294 295wi_boolean_t wi_socket_tls_set_certificate(wi_socket_tls_t *tls, wi_x509_t *x509) { 296 if(SSL_CTX_use_certificate(tls->ssl_ctx, wi_x509_x509(x509)) != 1) { 297 wi_error_set_openssl_error(); 298 299 return false; 300 } 301 302 return true; 303} 304 305 306 307wi_boolean_t wi_socket_tls_set_private_key(wi_socket_tls_t *tls, wi_rsa_t *rsa) { 308 tls->private_key = false; 309 310 if(SSL_CTX_use_RSAPrivateKey(tls->ssl_ctx, wi_rsa_rsa(rsa)) != 1) { 311 wi_error_set_openssl_error(); 312 313 return false; 314 } 315 316 tls->private_key = true; 317 318 return true; 319} 320 321 322 323wi_boolean_t wi_socket_tls_set_ciphers(wi_socket_tls_t *tls, wi_string_t *ciphers) { 324 if(SSL_CTX_set_cipher_list(tls->ssl_ctx, wi_string_cstring(ciphers)) != 1) { 325 wi_error_set_libwired_error(WI_ERROR_SOCKET_NOVALIDCIPHER); 326 327 return false; 328 } 329 330 return true; 331} 332 333 334 335wi_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) { 336 tls->dh = DH_new(); 337 338 if(!tls->dh) { 339 wi_error_set_openssl_error(); 340 341 return false; 342 } 343 344 tls->dh->p = BN_bin2bn(p, p_size, NULL); 345 tls->dh->g = BN_bin2bn(g, g_size, NULL); 346 347 if(!tls->dh->p || !tls->dh->g) { 348 wi_error_set_openssl_error(); 349 350 DH_free(tls->dh); 351 tls->dh = NULL; 352 353 return false; 354 } 355 356 return true; 357} 358 359#endif 360 361 362 363#pragma mark - 364 365wi_runtime_id_t wi_socket_runtime_id(void) { 366 return _wi_socket_runtime_id; 367} 368 369 370 371#pragma mark - 372 373wi_socket_t * wi_socket_with_address(wi_address_t *address, wi_socket_type_t type) { 374 return wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, type)); 375} 376 377 378 379#pragma mark - 380 381wi_socket_t * wi_socket_alloc(void) { 382 return wi_runtime_create_instance(_wi_socket_runtime_id, sizeof(wi_socket_t)); 383} 384 385 386 387wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) { 388 _socket->address = wi_copy(address); 389 _socket->close = true; 390 _socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE); 391 _socket->type = type; 392 393 _socket->sd = socket(wi_address_family(_socket->address), _socket->type, 0); 394 395 if(_socket->sd < 0) { 396 wi_error_set_errno(errno); 397 398 wi_release(_socket); 399 400 return NULL; 401 } 402 403 if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) { 404 wi_release(_socket); 405 406 return NULL; 407 } 408 409#ifdef SO_REUSEPORT 410 if(!_wi_socket_set_option_int(_socket, SOL_SOCKET, SO_REUSEPORT, 1)) { 411 wi_release(_socket); 412 413 return NULL; 414 } 415#endif 416 417 return _socket; 418} 419 420 421 422wi_socket_t * wi_socket_init_with_descriptor(wi_socket_t *socket, int sd) { 423 socket->sd = sd; 424 socket->buffer = wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE); 425 426 return socket; 427} 428 429 430 431static void _wi_socket_dealloc(wi_runtime_instance_t *instance) { 432 wi_socket_t *socket = instance; 433 434 wi_socket_close(socket); 435 436 wi_release(socket->address); 437 wi_release(socket->buffer); 438} 439 440 441 442static wi_string_t * _wi_socket_description(wi_runtime_instance_t *instance) { 443 wi_socket_t *socket = instance; 444 445 return wi_string_with_format(WI_STR("<%@ %p>{sd = %d, address = %@}"), 446 wi_runtime_class_name(socket), 447 socket, 448 socket->sd, 449 socket->address); 450} 451 452 453 454#pragma mark - 455 456static wi_boolean_t _wi_socket_set_option_int(wi_socket_t *socket, int level, int name, int option) { 457 if(setsockopt(socket->sd, level, name, &option, sizeof(option)) < 0) { 458 wi_error_set_errno(errno); 459 460 return false; 461 } 462 463 return true; 464} 465 466 467 468static wi_boolean_t _wi_socket_get_option_int(wi_socket_t *socket, int level, int name, int *option) { 469 socklen_t length; 470 471 length = sizeof(*option); 472 473 if(getsockopt(socket->sd, level, name, option, &length) < 0) { 474 wi_error_set_errno(errno); 475 476 *option = 0; 477 478 return false; 479 } 480 481 return true; 482} 483 484 485 486#pragma mark - 487 488wi_address_t * wi_socket_address(wi_socket_t *socket) { 489 return socket->address; 490} 491 492 493 494int wi_socket_descriptor(wi_socket_t *socket) { 495 return socket->sd; 496} 497 498 499 500void * wi_socket_ssl(wi_socket_t *socket) { 501#ifdef HAVE_OPENSSL_SSL_H 502 return socket->ssl; 503#else 504 return NULL; 505#endif 506} 507 508 509 510wi_rsa_t * wi_socket_ssl_public_key(wi_socket_t *socket) { 511#ifdef HAVE_OPENSSL_SSL_H 512 RSA *rsa = NULL; 513 X509 *x509 = NULL; 514 EVP_PKEY *pkey = NULL; 515 516 x509 = SSL_get_peer_certificate(socket->ssl); 517 518 if(!x509) { 519 wi_error_set_openssl_error(); 520 521 goto end; 522 } 523 524 pkey = X509_get_pubkey(x509); 525 526 if(!pkey) { 527 wi_error_set_openssl_error(); 528 529 goto end; 530 } 531 532 rsa = EVP_PKEY_get1_RSA(pkey); 533 534 if(!rsa) 535 wi_error_set_openssl_error(); 536 537end: 538 if(x509) 539 X509_free(x509); 540 541 if(pkey) 542 EVP_PKEY_free(pkey); 543 544 return wi_autorelease(wi_rsa_init_with_rsa(wi_rsa_alloc(), rsa)); 545#else 546 return NULL; 547#endif 548} 549 550 551 552wi_string_t * wi_socket_cipher_version(wi_socket_t *socket) { 553#ifdef HAVE_OPENSSL_SSL_H 554 return wi_string_with_cstring(SSL_get_cipher_version(socket->ssl)); 555#else 556 return NULL; 557#endif 558} 559 560 561 562wi_string_t * wi_socket_cipher_name(wi_socket_t *socket) { 563#ifdef HAVE_OPENSSL_SSL_H 564 return wi_string_with_cstring(SSL_get_cipher_name(socket->ssl)); 565#else 566 return NULL; 567#endif 568} 569 570 571 572wi_uinteger_t wi_socket_cipher_bits(wi_socket_t *socket) { 573#ifdef HAVE_OPENSSL_SSL_H 574 return SSL_get_cipher_bits(socket->ssl, NULL); 575#else 576 return 0; 577#endif 578} 579 580 581 582wi_string_t * wi_socket_certificate_name(wi_socket_t *socket) { 583#ifdef HAVE_OPENSSL_SSL_H 584 X509 *x509 = NULL; 585 EVP_PKEY *pkey = NULL; 586 wi_string_t *string = NULL; 587 588 x509 = SSL_get_peer_certificate(socket->ssl); 589 590 if(!x509) 591 goto end; 592 593 pkey = X509_get_pubkey(x509); 594 595 if(!pkey) 596 goto end; 597 598 switch(EVP_PKEY_type(pkey->type)) { 599 case EVP_PKEY_RSA: 600 string = wi_string_init_with_cstring(wi_string_alloc(), "RSA"); 601 break; 602 603 case EVP_PKEY_DSA: 604 string = wi_string_init_with_cstring(wi_string_alloc(), "DSA"); 605 break; 606 607 case EVP_PKEY_DH: 608 string = wi_string_init_with_cstring(wi_string_alloc(), "DH"); 609 break; 610 611 default: 612 break; 613 } 614 615end: 616 if(x509) 617 X509_free(x509); 618 619 if(pkey) 620 EVP_PKEY_free(pkey); 621 622 return wi_autorelease(string); 623#else 624 return NULL; 625#endif 626} 627 628 629 630wi_uinteger_t wi_socket_certificate_bits(wi_socket_t *socket) { 631#ifdef HAVE_OPENSSL_SSL_H 632 X509 *x509 = NULL; 633 EVP_PKEY *pkey = NULL; 634 wi_uinteger_t bits = 0; 635 636 x509 = SSL_get_peer_certificate(socket->ssl); 637 638 if(!x509) 639 goto end; 640 641 pkey = X509_get_pubkey(x509); 642 643 if(!pkey) 644 goto end; 645 646 bits = 8 * EVP_PKEY_size(pkey); 647 648end: 649 if(x509) 650 X509_free(x509); 651 652 if(pkey) 653 EVP_PKEY_free(pkey); 654 655 return bits; 656#else 657 return 0; 658#endif 659} 660 661 662 663wi_string_t * wi_socket_certificate_hostname(wi_socket_t *socket) { 664#ifdef HAVE_OPENSSL_SSL_H 665 X509 *x509; 666 wi_string_t *string; 667 char hostname[MAXHOSTNAMELEN]; 668 669 x509 = SSL_get_peer_certificate(socket->ssl); 670 671 if(!x509) 672 return NULL; 673 674 X509_NAME_get_text_by_NID(X509_get_subject_name(x509), 675 NID_commonName, 676 hostname, 677 sizeof(hostname)); 678 679 string = wi_string_init_with_cstring(wi_string_alloc(), hostname); 680 681 X509_free(x509); 682 683 return wi_autorelease(string); 684#else 685 return NULL; 686#endif 687} 688 689 690 691#pragma mark - 692 693void wi_socket_set_port(wi_socket_t *socket, wi_uinteger_t port) { 694 wi_address_set_port(socket->address, port); 695} 696 697 698 699wi_uinteger_t wi_socket_port(wi_socket_t *socket) { 700 return wi_address_port(socket->address); 701} 702 703 704 705void wi_socket_set_direction(wi_socket_t *socket, wi_uinteger_t direction) { 706 socket->direction = direction; 707} 708 709 710 711wi_uinteger_t wi_socket_direction(wi_socket_t *socket) { 712 return socket->direction; 713} 714 715 716 717void wi_socket_set_data(wi_socket_t *socket, void *data) { 718 socket->data = data; 719} 720 721 722 723void * wi_socket_data(wi_socket_t *socket) { 724 return socket->data; 725} 726 727 728 729 730wi_boolean_t wi_socket_set_blocking(wi_socket_t *socket, wi_boolean_t blocking) { 731 int flags; 732 733 flags = fcntl(socket->sd, F_GETFL); 734 735 if(flags < 0) { 736 wi_error_set_errno(errno); 737 738 return false; 739 } 740 741 if(blocking) 742 flags &= ~O_NONBLOCK; 743 else 744 flags |= O_NONBLOCK; 745 746 if(fcntl(socket->sd, F_SETFL, flags) < 0) { 747 wi_error_set_errno(errno); 748 749 return false; 750 } 751 752 return true; 753} 754 755 756 757wi_boolean_t wi_socket_blocking(wi_socket_t *socket) { 758 int flags; 759 760 flags = fcntl(socket->sd, F_GETFL); 761 762 if(flags < 0) { 763 wi_error_set_errno(errno); 764 765 return false; 766 } 767 768 return !(flags & O_NONBLOCK); 769} 770 771 772 773wi_boolean_t wi_socket_set_timeout(wi_socket_t *socket, wi_time_interval_t interval) { 774 struct timeval tv; 775 776 tv = wi_dtotv(interval); 777 778 if(setsockopt(socket->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { 779 wi_error_set_errno(errno); 780 781 return false; 782 } 783 784 if(setsockopt(socket->sd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) { 785 wi_error_set_errno(errno); 786 787 return false; 788 } 789 790 return true; 791} 792 793 794 795wi_time_interval_t wi_socket_timeout(wi_socket_t *socket) { 796 struct timeval tv; 797 socklen_t length; 798 799 length = sizeof(tv); 800 801 if(getsockopt(socket->sd, SOL_SOCKET, SO_RCVTIMEO, &tv, &length) < 0) { 802 wi_error_set_errno(errno); 803 804 return 0.0; 805 } 806 807 return wi_tvtod(tv); 808} 809 810 811 812void wi_socket_set_interactive(wi_socket_t *socket, wi_boolean_t interactive) { 813 _wi_socket_set_option_int(socket, IPPROTO_TCP, TCP_NODELAY, interactive ? 1 : 0); 814 815#if defined(IPTOS_LOWDELAY) && defined(IPTOS_THROUGHPUT) 816 if(wi_address_family(socket->address) == WI_ADDRESS_IPV4) 817 _wi_socket_set_option_int(socket, IPPROTO_IP, IP_TOS, interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT); 818#endif 819 820 socket->interactive = interactive; 821} 822 823 824 825wi_boolean_t wi_socket_interactive(wi_socket_t *socket) { 826 return socket->interactive; 827} 828 829 830 831int wi_socket_error(wi_socket_t *socket) { 832 int error; 833 834 WI_ASSERT(socket->type == WI_SOCKET_TCP, "%@ is not a TCP socket", socket); 835 836 if(!_wi_socket_get_option_int(socket, SOL_SOCKET, SO_ERROR, &error)) 837 return errno; 838 839 return error; 840} 841 842 843 844#pragma mark - 845 846wi_socket_t * wi_socket_wait_multiple(wi_array_t *array, wi_time_interval_t timeout) { 847 wi_enumerator_t *enumerator; 848 wi_socket_t *socket, *waiting_socket = NULL; 849 struct timeval tv; 850 fd_set rfds, wfds; 851 int state, max_sd; 852 853 tv = wi_dtotv(timeout); 854 max_sd = -1; 855 856 FD_ZERO(&rfds); 857 FD_ZERO(&wfds); 858 859 wi_array_rdlock(array); 860 861 enumerator = wi_array_data_enumerator(array); 862 863 while((socket = wi_enumerator_next_data(enumerator))) { 864 if(wi_string_length(socket->buffer) > 0) { 865 waiting_socket = socket; 866 867 break; 868 } 869 870 if(socket->direction & WI_SOCKET_READ) 871 FD_SET(socket->sd, &rfds); 872 873 if(socket->direction & WI_SOCKET_WRITE) 874 FD_SET(socket->sd, &wfds); 875 876 if(socket->sd > max_sd) 877 max_sd = socket->sd; 878 } 879 880 wi_array_unlock(array); 881 882 if(waiting_socket) 883 return waiting_socket; 884 885 state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL); 886 887 if(state < 0) { 888 wi_error_set_errno(errno); 889 890 return NULL; 891 } 892 893 wi_array_rdlock(array); 894 895 enumerator = wi_array_data_enumerator(array); 896 897 while((socket = wi_enumerator_next_data(enumerator))) { 898 if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) { 899 waiting_socket = socket; 900 901 break; 902 } 903 } 904 905 wi_array_unlock(array); 906 907 return waiting_socket; 908} 909 910 911 912wi_socket_state_t wi_socket_wait(wi_socket_t *socket, wi_time_interval_t timeout) { 913 if(wi_string_length(socket->buffer) > 0) 914 return WI_SOCKET_READY; 915 916 return wi_socket_wait_descriptor(socket->sd, 917 timeout, 918 (socket->direction & WI_SOCKET_READ), 919 (socket->direction & WI_SOCKET_WRITE)); 920} 921 922 923 924wi_socket_state_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) { 925 struct timeval tv; 926 fd_set rfds, wfds; 927 int state; 928 929 tv = wi_dtotv(timeout); 930 931 FD_ZERO(&rfds); 932 FD_ZERO(&wfds); 933 934 if(read) 935 FD_SET(sd, &rfds); 936 937 if(write) 938 FD_SET(sd, &wfds); 939 940 state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL); 941 942 if(state < 0) { 943 wi_error_set_errno(errno); 944 945 return WI_SOCKET_ERROR; 946 } 947 948 if(state == 0) 949 return WI_SOCKET_TIMEOUT; 950 951 return WI_SOCKET_READY; 952} 953 954 955 956#pragma mark - 957 958wi_boolean_t wi_socket_listen(wi_socket_t *socket, wi_uinteger_t backlog) { 959 struct sockaddr *sa; 960 struct sockaddr_storage ss; 961 wi_uinteger_t port; 962 socklen_t length; 963 964 port = wi_address_port(socket->address); 965 sa = wi_address_sa(socket->address); 966 length = wi_address_sa_length(socket->address); 967 968 if(bind(socket->sd, sa, length) < 0) { 969 wi_error_set_errno(errno); 970 971 return false; 972 } 973 974 if(socket->type == WI_SOCKET_TCP) { 975 if(listen(socket->sd, backlog) < 0) { 976 wi_error_set_errno(errno); 977 978 return false; 979 } 980 } 981 982 if(port == 0) { 983 length = sizeof(ss); 984 985 if(getsockname(socket->sd, (struct sockaddr *) &ss, &length) == 0) { 986 wi_release(socket->address); 987 socket->address = wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss); 988 } 989 } 990 991 socket->direction = WI_SOCKET_READ; 992 993 return true; 994} 995 996 997 998wi_boolean_t wi_socket_connect(wi_socket_t *socket, wi_time_interval_t timeout) { 999 struct sockaddr *sa; 1000 wi_socket_state_t state; 1001 wi_uinteger_t length; 1002 int err; 1003 wi_boolean_t blocking; 1004 1005 sa = wi_address_sa(socket->address); 1006 length = wi_address_sa_length(socket->address); 1007 1008 if(timeout > 0.0) { 1009 blocking = wi_socket_blocking(socket); 1010 1011 if(blocking) 1012 wi_socket_set_blocking(socket, false); 1013 1014 err = connect(socket->sd, sa, length); 1015 1016 if(err < 0) { 1017 if(errno != EINPROGRESS) { 1018 wi_error_set_errno(errno); 1019 1020 return false; 1021 } 1022 1023 do { 1024 state = wi_socket_wait_descriptor(socket->sd, 1.0, true, true); 1025 timeout -= 1.0; 1026 } while(state == WI_SOCKET_TIMEOUT && timeout >= 0.0); 1027 1028 if(state == WI_SOCKET_ERROR) 1029 return false; 1030 1031 if(timeout <= 0.0) { 1032 wi_error_set_errno(ETIMEDOUT); 1033 1034 return false; 1035 } 1036 1037 err = wi_socket_error(socket); 1038 1039 if(err != 0) { 1040 wi_error_set_errno(err); 1041 1042 return false; 1043 } 1044 } 1045 1046 if(blocking) 1047 wi_socket_set_blocking(socket, true); 1048 } else { 1049 if(connect(socket->sd, sa, length) < 0) { 1050 wi_error_set_errno(errno); 1051 1052 return false; 1053 } 1054 } 1055 1056 socket->direction = WI_SOCKET_READ; 1057 1058 return true; 1059} 1060 1061 1062 1063#ifdef HAVE_OPENSSL_SSL_H 1064 1065wi_boolean_t wi_socket_connect_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) { 1066 wi_socket_state_t state; 1067 int err, result; 1068 wi_boolean_t blocking; 1069 1070 socket->ssl = SSL_new(tls->ssl_ctx); 1071 1072 if(!socket->ssl) { 1073 wi_error_set_openssl_error(); 1074 1075 return false; 1076 } 1077 1078 if(SSL_set_fd(socket->ssl, socket->sd) != 1) { 1079 wi_error_set_openssl_error(); 1080 1081 return false; 1082 } 1083 1084 if(timeout > 0.0) { 1085 blocking = wi_socket_blocking(socket); 1086 1087 if(blocking) 1088 wi_socket_set_blocking(socket, false); 1089 1090 result = SSL_connect(socket->ssl); 1091 1092 if(result != 1) { 1093 do { 1094 err = SSL_get_error(socket->ssl, result); 1095 1096 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { 1097 wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); 1098 1099 return false; 1100 } 1101 1102 state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE)); 1103 1104 if(state == WI_SOCKET_ERROR) 1105 break; 1106 else if(state == WI_SOCKET_READY) { 1107 result = SSL_connect(socket->ssl); 1108 1109 if(result == 1) 1110 break; 1111 } 1112 1113 timeout -= 1.0; 1114 } while(timeout >= 0.0); 1115 1116 if(state == WI_SOCKET_ERROR) 1117 return false; 1118 1119 if(timeout <= 0.0) { 1120 wi_error_set_errno(ETIMEDOUT); 1121 1122 return false; 1123 } 1124 } 1125 1126 if(blocking) 1127 wi_socket_set_blocking(socket, true); 1128 } else { 1129 result = SSL_connect(socket->ssl); 1130 1131 if(result != 1) { 1132 wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); 1133 1134 return false; 1135 } 1136 } 1137 1138 return true; 1139} 1140 1141#endif 1142 1143 1144 1145wi_socket_t * wi_socket_accept_multiple(wi_array_t *array, wi_time_interval_t timeout, wi_address_t **address) { 1146 wi_socket_t *socket; 1147 1148 *address = NULL; 1149 socket = wi_socket_wait_multiple(array, 0.0); 1150 1151 if(!socket) 1152 return NULL; 1153 1154 return wi_socket_accept(socket, timeout, address); 1155} 1156 1157 1158 1159wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_time_interval_t timeout, wi_address_t **address) { 1160 wi_socket_t *socket; 1161 struct sockaddr_storage ss; 1162 socklen_t length; 1163 int sd, err = 0; 1164 1165 length = sizeof(ss); 1166 sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length); 1167 1168 if(sd < 0) 1169 err = errno; 1170 1171 *address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL; 1172 1173 if(sd < 0) { 1174 wi_error_set_errno(err); 1175 1176 return NULL; 1177 } 1178 1179 socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd); 1180 1181 socket->close = true; 1182 socket->address = wi_retain(*address); 1183 socket->type = accept_socket->type; 1184 socket->direction = WI_SOCKET_READ; 1185 socket->interactive = accept_socket->interactive; 1186 1187 return wi_autorelease(socket); 1188} 1189 1190 1191 1192#ifdef HAVE_OPENSSL_SSL_H 1193 1194wi_boolean_t wi_socket_accept_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) { 1195 wi_socket_state_t state; 1196 int err, result; 1197 wi_boolean_t blocking; 1198 1199 socket->ssl = SSL_new(tls->ssl_ctx); 1200 1201 if(!socket->ssl) { 1202 wi_error_set_openssl_error(); 1203 1204 return false; 1205 } 1206 1207 if(SSL_set_fd(socket->ssl, socket->sd) != 1) { 1208 wi_error_set_openssl_error(); 1209 1210 return false; 1211 } 1212 1213 if(!tls->private_key && tls->dh) { 1214 if(SSL_set_tmp_dh(socket->ssl, tls->dh) != 1) { 1215 wi_error_set_openssl_error(); 1216 1217 return false; 1218 } 1219 } 1220 1221 if(timeout > 0.0) { 1222 blocking = wi_socket_blocking(socket); 1223 1224 if(blocking) 1225 wi_socket_set_blocking(socket, false); 1226 1227 result = SSL_accept(socket->ssl); 1228 1229 if(result != 1) { 1230 do { 1231 err = SSL_get_error(socket->ssl, result); 1232 1233 if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { 1234 wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); 1235 1236 return false; 1237 } 1238 1239 state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE)); 1240 1241 if(state == WI_SOCKET_ERROR) 1242 break; 1243 else if(state == WI_SOCKET_READY) { 1244 result = SSL_accept(socket->ssl); 1245 1246 if(result == 1) 1247 break; 1248 } 1249 1250 timeout -= 1.0; 1251 } while(timeout >= 0.0); 1252 1253 if(state == WI_SOCKET_ERROR) 1254 return false; 1255 1256 if(timeout <= 0.0) { 1257 wi_error_set_errno(ETIMEDOUT); 1258 1259 return false; 1260 } 1261 } 1262 1263 if(blocking) 1264 wi_socket_set_blocking(socket, true); 1265 } else { 1266 result = SSL_accept(socket->ssl); 1267 1268 if(result != 1) { 1269 wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); 1270 1271 return false; 1272 } 1273 } 1274 1275 return true; 1276} 1277 1278#endif 1279 1280 1281 1282void wi_socket_close(wi_socket_t *socket) { 1283#ifdef HAVE_OPENSSL_SSL_H 1284 if(socket->ssl) { 1285 if(!socket->broken) { 1286 if(SSL_shutdown(socket->ssl) == 0) 1287 SSL_shutdown(socket->ssl); 1288 } 1289 1290 SSL_free(socket->ssl); 1291 1292 socket->ssl = NULL; 1293 } 1294#endif 1295 1296 if(socket->close && socket->sd >= 0) { 1297 close(socket->sd); 1298 1299 socket->sd = -1; 1300 } 1301} 1302 1303 1304 1305#pragma mark - 1306 1307wi_integer_t wi_socket_sendto_format(wi_socket_t *socket, wi_string_t *fmt, ...) { 1308 wi_string_t *string; 1309 int bytes; 1310 va_list ap; 1311 1312 va_start(ap, fmt); 1313 string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap); 1314 va_end(ap); 1315 1316 bytes = wi_socket_sendto_buffer(socket, wi_string_cstring(string), wi_string_length(string)); 1317 1318 wi_release(string); 1319 1320 return bytes; 1321} 1322 1323 1324 1325wi_integer_t wi_socket_sendto_data(wi_socket_t *socket, wi_data_t *data) { 1326 return wi_socket_sendto_buffer(socket, wi_data_bytes(data), wi_data_length(data)); 1327} 1328 1329 1330 1331wi_integer_t wi_socket_sendto_buffer(wi_socket_t *socket, const char *buffer, size_t length) { 1332 wi_address_t *address; 1333 char *outbuffer = NULL; 1334 wi_integer_t bytes; 1335 1336 address = wi_socket_address(socket); 1337 bytes = sendto(socket->sd, buffer, length, 0, 1338 wi_address_sa(address), wi_address_sa_length(address)); 1339 1340 if(bytes < 0) { 1341 wi_error_set_errno(errno); 1342 1343 goto end; 1344 } 1345 1346end: 1347 if(outbuffer) 1348 wi_free(outbuffer); 1349 1350 return bytes; 1351} 1352 1353 1354 1355wi_integer_t wi_socket_recvfrom_multiple(wi_array_t *array, char *buffer, size_t length, wi_address_t **address) { 1356 wi_socket_t *socket; 1357 1358 *address = NULL; 1359 socket = wi_socket_wait_multiple(array, 0.0); 1360 1361 if(!socket) 1362 return -1; 1363 1364 return wi_socket_recvfrom(socket, buffer, length, address); 1365} 1366 1367 1368 1369wi_integer_t wi_socket_recvfrom(wi_socket_t *socket, char *buffer, size_t length, wi_address_t **address) { 1370 struct sockaddr_storage ss; 1371 char *inbuffer = NULL; 1372 socklen_t sslength; 1373 wi_integer_t bytes; 1374 1375 sslength = sizeof(ss); 1376 bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength); 1377 1378 if(bytes < 0) { 1379 wi_error_set_errno(errno); 1380 1381 goto end; 1382 } 1383 1384end: 1385 *address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL; 1386 1387 if(inbuffer) 1388 wi_free(inbuffer); 1389 1390 return bytes; 1391} 1392 1393 1394 1395#pragma mark - 1396 1397wi_integer_t wi_socket_write_format(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *fmt, ...) { 1398 wi_string_t *string; 1399 wi_integer_t bytes; 1400 va_list ap; 1401 1402 va_start(ap, fmt); 1403 string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap); 1404 va_end(ap); 1405 1406 bytes = wi_socket_write_buffer(socket, timeout, wi_string_cstring(string), wi_string_length(string)); 1407 1408 wi_release(string); 1409 1410 return bytes; 1411} 1412 1413 1414 1415wi_integer_t wi_socket_write_buffer(wi_socket_t *socket, wi_time_interval_t timeout, const void *buffer, size_t length) { 1416 wi_time_interval_t interval; 1417 wi_socket_state_t state; 1418 wi_uinteger_t offset; 1419 wi_integer_t bytes; 1420 1421 WI_ASSERT(buffer != NULL, "buffer of length %u should not be NULL", length); 1422 1423 if(timeout > 0.0) { 1424 state = wi_socket_wait_descriptor(socket->sd, timeout, false, true); 1425 1426 if(state != WI_SOCKET_READY) { 1427 if(state == WI_SOCKET_TIMEOUT) 1428 wi_error_set_errno(ETIMEDOUT); 1429 1430 return -1; 1431 } 1432 } 1433 1434 interval = 0.0; 1435 1436#ifdef HAVE_OPENSSL_SSL_H 1437 if(socket->ssl) { 1438 do { 1439 bytes = SSL_write(socket->ssl, buffer, length); 1440 1441 if(bytes <= 0) { 1442 if(bytes < 0 && SSL_get_error(socket->ssl, bytes) == SSL_ERROR_WANT_WRITE) { 1443 wi_thread_sleep(0.1); 1444 1445 if(timeout > 0.0) { 1446 interval += 0.1; 1447 1448 if(interval >= timeout) { 1449 wi_error_set_errno(ETIMEDOUT); 1450 1451 break; 1452 } 1453 } 1454 } else { 1455 wi_error_set_openssl_ssl_error_with_result(socket->ssl, bytes); 1456 1457 socket->broken = true; 1458 1459 break; 1460 } 1461 } 1462 } while(bytes <= 0); 1463 1464 return bytes; 1465 } else { 1466#endif 1467 offset = 0; 1468 1469 do { 1470 bytes = write(socket->sd, buffer + offset, length - offset); 1471 1472 if(bytes <= 0) { 1473 if(bytes < 0) 1474 wi_error_set_errno(errno); 1475 else 1476 wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF); 1477 1478 return bytes; 1479 } 1480 1481 offset += bytes; 1482 1483 if(offset < length) { 1484 wi_thread_sleep(0.1); 1485 1486 if(timeout > 0.0) { 1487 interval += 0.1; 1488 1489 if(interval >= timeout) { 1490 wi_error_set_errno(ETIMEDOUT); 1491 1492 return -1; 1493 } 1494 } 1495 } 1496 } while(offset < length); 1497 1498 return offset; 1499#ifdef HAVE_OPENSSL_SSL_H 1500 } 1501#endif 1502 1503 return 0; 1504} 1505 1506 1507 1508wi_string_t * wi_socket_read(wi_socket_t *socket, wi_time_interval_t timeout, size_t length) { 1509 wi_string_t *string; 1510 char buffer[WI_SOCKET_BUFFER_SIZE]; 1511 int bytes = -1; 1512 1513 string = wi_string_init_with_capacity(wi_string_alloc(), length); 1514 1515 while(length > sizeof(buffer)) { 1516 bytes = wi_socket_read_buffer(socket, timeout, buffer, sizeof(buffer)); 1517 1518 if(bytes <= 0) 1519 goto end; 1520 1521 wi_string_append_bytes(string, buffer, bytes); 1522 1523 length -= bytes; 1524 } 1525 1526 if(length > 0) { 1527 bytes = wi_socket_read_buffer(socket, timeout, buffer, length); 1528 1529 if(bytes <= 0) 1530 goto end; 1531 1532 wi_string_append_bytes(string, buffer, bytes); 1533 } 1534 1535end: 1536 if(wi_string_length(string) == 0) { 1537 if(bytes < 0) { 1538 wi_release(string); 1539 1540 string = NULL; 1541 } 1542 } 1543 1544 return wi_autorelease(string); 1545} 1546 1547 1548 1549wi_string_t * wi_socket_read_to_string(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *separator) { 1550 wi_string_t *string, *substring; 1551 wi_uinteger_t index; 1552 1553 index = wi_string_index_of_string(socket->buffer, separator, 0); 1554 1555 if(index != WI_NOT_FOUND) { 1556 substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator)); 1557 1558 wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring))); 1559 1560 return substring; 1561 } 1562 1563 while((string = wi_socket_read(socket, timeout, WI_SOCKET_BUFFER_SIZE))) { 1564 if(wi_string_length(string) == 0) 1565 return string; 1566 1567 wi_string_append_string(socket->buffer, string); 1568 1569 index = wi_string_index_of_string(socket->buffer, separator, 0); 1570 1571 if(index == WI_NOT_FOUND) { 1572 if(wi_string_length(socket->buffer) > _WI_SOCKET_BUFFER_MAX_SIZE) { 1573 substring = wi_string_substring_to_index(socket->buffer, _WI_SOCKET_BUFFER_MAX_SIZE); 1574 1575 wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring))); 1576 1577 return substring; 1578 } 1579 } else { 1580 substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator)); 1581 1582 wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring))); 1583 1584 return substring; 1585 } 1586 } 1587 1588 return NULL; 1589} 1590 1591 1592 1593wi_integer_t wi_socket_read_buffer(wi_socket_t *socket, wi_time_interval_t timeout, void *buffer, size_t length) { 1594 wi_time_interval_t interval; 1595 wi_socket_state_t state; 1596 wi_uinteger_t offset; 1597 wi_integer_t bytes; 1598 1599 WI_ASSERT(buffer != NULL, "buffer of length %u should not be NULL", length); 1600 1601 if(timeout > 0.0) { 1602#ifdef HAVE_OPENSSL_SSL_H 1603 if(!socket->ssl || (socket->ssl && SSL_pending(socket->ssl) == 0)) { 1604#endif 1605 state = wi_socket_wait_descriptor(socket->sd, timeout, true, false); 1606 1607 if(state != WI_SOCKET_READY) { 1608 if(state == WI_SOCKET_TIMEOUT) 1609 wi_error_set_errno(ETIMEDOUT); 1610 1611 return -1; 1612 } 1613#ifdef HAVE_OPENSSL_SSL_H 1614 } 1615#endif 1616 } 1617 1618 interval = 0.0; 1619 1620#ifdef HAVE_OPENSSL_SSL_H 1621 if(socket->ssl) { 1622 do { 1623 bytes = SSL_read(socket->ssl, buffer, length); 1624 1625 if(bytes <= 0) { 1626 if(bytes < 0 && SSL_get_error(socket->ssl, bytes) == SSL_ERROR_WANT_READ) { 1627 wi_thread_sleep(0.1); 1628 1629 if(timeout > 0.0) { 1630 interval += 0.1; 1631 1632 if(interval >= timeout) { 1633 wi_error_set_errno(ETIMEDOUT); 1634 1635 break; 1636 } 1637 } 1638 } else { 1639 wi_error_set_openssl_ssl_error_with_result(socket->ssl, bytes); 1640 1641 socket->broken = true; 1642 1643 break; 1644 } 1645 } 1646 } while(bytes <= 0); 1647 1648 return bytes; 1649 } else { 1650#endif 1651 offset = 0; 1652 1653 do { 1654 bytes = read(socket->sd, buffer + offset, length - offset); 1655 1656 if(bytes <= 0) { 1657 if(bytes < 0) 1658 wi_error_set_errno(errno); 1659 else 1660 wi_error_set_libwired_error(WI_ERROR_SOCKET_EOF); 1661 1662 return bytes; 1663 } 1664 1665 offset += bytes; 1666 1667 if(offset < length) { 1668 wi_thread_sleep(0.1); 1669 1670 if(timeout > 0.0) { 1671 interval += 0.1; 1672 1673 if(interval >= timeout) { 1674 wi_error_set_errno(ETIMEDOUT); 1675 1676 return -1; 1677 } 1678 } 1679 } 1680 } while(offset < length); 1681 1682 return offset; 1683#ifdef HAVE_OPENSSL_SSL_H 1684 } 1685#endif 1686 1687 return 0; 1688} 1689 1690 1691 1692#pragma mark - 1693 1694wi_string_t * wi_socket_buffered_string(wi_socket_t *socket) { 1695 return socket->buffer; 1696}