PageRenderTime 59ms CodeModel.GetById 2ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 1ms

/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/*
   4 *  Copyright (c) 2003-2006 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#include <netinet/in_systm.h>
  37#include <netinet/ip.h>
  38#include <netinet/tcp.h>
  39#include <netdb.h>
  40#include <net/if.h>
  41#include <fcntl.h>
  42#include <unistd.h>
  43#include <stdio.h>
  44#include <string.h>
  45#include <errno.h>
  46
  47#ifdef WI_SSL
  48#include <openssl/err.h>
  49#include <openssl/ssl.h>
  50#endif
  51
  52#ifdef HAVE_IFADDRS_H
  53#include <ifaddrs.h>
  54#endif
  55
  56#include <wired/wi-array.h>
  57#include <wired/wi-assert.h>
  58#include <wired/wi-address.h>
  59#include <wired/wi-date.h>
  60#include <wired/wi-macros.h>
  61#include <wired/wi-list.h>
  62#include <wired/wi-lock.h>
  63#include <wired/wi-socket.h>
  64#include <wired/wi-string.h>
  65#include <wired/wi-system.h>
  66#include <wired/wi-thread.h>
  67
  68#include "wi-private.h"
  69
  70#define _WI_SOCKET_BUFFER_MAX_SIZE		131072
  71
  72
  73struct _wi_socket_context {
  74	wi_runtime_base_t					base;
  75	
  76#ifdef WI_SSL
  77	SSL_CTX								*ssl_ctx;
  78	DH									*dh;
  79	
  80	RSA									*pub_rsa;
  81	RSA									*priv_rsa;
  82	
  83	wi_boolean_t						certificate;
  84#endif
  85};
  86
  87
  88struct _wi_socket {
  89	wi_runtime_base_t					base;
  90	
  91	wi_address_t						*address;
  92	wi_socket_type_t					type;
  93	uint32_t							direction;
  94	int									sd;
  95
  96#ifdef WI_SSL
  97	SSL									*ssl;
  98#endif
  99	
 100	void								*data;
 101	
 102	wi_string_t							*buffer;
 103	
 104	wi_boolean_t						interactive;
 105	wi_boolean_t						close;
 106	wi_boolean_t						broken;
 107};
 108
 109
 110#if defined(WI_SSL) && defined(WI_PTHREADS)
 111static unsigned long					_wi_socket_ssl_id_function(void);
 112static void								_wi_socket_ssl_locking_function(int, int, const char *, int);
 113#endif
 114
 115static void								_wi_socket_context_dealloc(wi_runtime_instance_t *);
 116
 117static void								_wi_socket_dealloc(wi_runtime_instance_t *);
 118static wi_string_t *					_wi_socket_description(wi_runtime_instance_t *);
 119
 120static wi_boolean_t						_wi_socket_set_option(wi_socket_t *, int, int, int);
 121static wi_boolean_t						_wi_socket_get_option(wi_socket_t *, int, int, int *);
 122
 123
 124#if defined(WI_SSL) && defined(WI_PTHREADS)
 125static wi_array_t						*_wi_socket_ssl_locks;
 126#endif
 127
 128static wi_runtime_id_t					_wi_socket_context_runtime_id = WI_RUNTIME_ID_NULL;
 129static wi_runtime_class_t				_wi_socket_context_runtime_class = {
 130	"wi_socket_context_t",
 131	_wi_socket_context_dealloc,
 132	NULL,
 133	NULL,
 134	NULL,
 135	NULL
 136};
 137
 138static wi_runtime_id_t					_wi_socket_runtime_id = WI_RUNTIME_ID_NULL;
 139static wi_runtime_class_t				_wi_socket_runtime_class = {
 140	"wi_socket_t",
 141	_wi_socket_dealloc,
 142	NULL,
 143	NULL,
 144	_wi_socket_description,
 145	NULL
 146};
 147
 148
 149void wi_socket_register(void) {
 150	_wi_socket_context_runtime_id = wi_runtime_register_class(&_wi_socket_context_runtime_class);
 151	_wi_socket_runtime_id = wi_runtime_register_class(&_wi_socket_runtime_class);
 152}
 153
 154
 155
 156void wi_socket_initialize(void) {
 157#ifdef WI_SSL
 158#ifdef WI_PTHREADS
 159	wi_lock_t		*lock;
 160	uint32_t		i, count;
 161#endif
 162
 163	SSL_library_init();
 164
 165#ifdef WI_PTHREADS
 166	count = CRYPTO_num_locks();
 167	_wi_socket_ssl_locks = wi_array_init_with_capacity(wi_array_alloc(), count);
 168	
 169	for(i = 0; i < count; i++) {
 170		lock = wi_lock_init(wi_lock_alloc());
 171		wi_array_add_data(_wi_socket_ssl_locks, lock);
 172		wi_release(lock);
 173	}
 174
 175	CRYPTO_set_id_callback(_wi_socket_ssl_id_function);
 176	CRYPTO_set_locking_callback(_wi_socket_ssl_locking_function);
 177#endif
 178#endif
 179}
 180
 181
 182
 183#pragma mark -
 184
 185#if defined(WI_SSL) && defined(WI_PTHREADS)
 186
 187static unsigned long _wi_socket_ssl_id_function(void) {
 188	return ((unsigned long) wi_thread_current_thread());
 189}
 190
 191
 192
 193static void _wi_socket_ssl_locking_function(int mode, int n, const char *file, int line) {
 194	wi_lock_t		*lock;
 195	
 196	lock = WI_ARRAY(_wi_socket_ssl_locks, n);
 197	
 198	if(mode & CRYPTO_LOCK)
 199		wi_lock_lock(lock);
 200	else
 201		wi_lock_unlock(lock);
 202}
 203
 204#endif
 205
 206
 207
 208#pragma mark -
 209
 210void wi_socket_exit_thread(void) {
 211#ifdef WI_SSL
 212	ERR_remove_state(0);
 213#endif
 214}
 215
 216
 217
 218#pragma mark -
 219
 220wi_runtime_id_t wi_socket_context_runtime_id(void) {
 221	return _wi_socket_context_runtime_id;
 222}
 223
 224
 225
 226#pragma mark -
 227
 228wi_socket_context_t * wi_socket_context_alloc(void) {
 229	return wi_runtime_create_instance(_wi_socket_context_runtime_id, sizeof(wi_socket_context_t));
 230}
 231
 232
 233
 234wi_socket_context_t * wi_socket_context_init(wi_socket_context_t *context) {
 235	return context;
 236}
 237
 238
 239
 240static void _wi_socket_context_dealloc(wi_runtime_instance_t *instance) {
 241#ifdef WI_SSL
 242	wi_socket_context_t		*context = instance;
 243	
 244	if(context->ssl_ctx)
 245		SSL_CTX_free(context->ssl_ctx);
 246	
 247	if(context->dh)
 248		DH_free(context->dh);
 249#endif
 250}
 251
 252
 253
 254#pragma mark -
 255
 256wi_boolean_t wi_socket_context_set_ssl_type(wi_socket_context_t *context, wi_socket_ssl_type_t type) {
 257#ifdef WI_SSL
 258	SSL_METHOD		*method = NULL;
 259	
 260	switch(type) {
 261		case WI_SOCKET_SSL_CLIENT:
 262			method = TLSv1_client_method();
 263			break;
 264
 265		case WI_SOCKET_SSL_SERVER:
 266			method = TLSv1_server_method();
 267			break;
 268	}
 269	
 270	context->ssl_ctx = SSL_CTX_new(method);
 271	
 272	if(!context->ssl_ctx)
 273		wi_error_set_ssl_error();
 274	
 275	return (context->ssl_ctx != NULL);
 276#else
 277	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
 278	
 279	return false;
 280#endif
 281}
 282
 283
 284
 285wi_boolean_t wi_socket_context_set_ssl_certificate(wi_socket_context_t *context, wi_string_t *path) {
 286#ifdef WI_SSL
 287	const char		*certificate;
 288	
 289	context->certificate = false;
 290	
 291	certificate = wi_string_cstring(path);
 292	
 293	if(SSL_CTX_use_certificate_chain_file(context->ssl_ctx, certificate) != 1) {
 294		wi_error_set_ssl_error();
 295
 296		return false;
 297	}
 298	
 299	if(SSL_CTX_use_PrivateKey_file(context->ssl_ctx, certificate, SSL_FILETYPE_PEM) != 1) {
 300		wi_error_set_ssl_error();
 301
 302		return false;
 303	}
 304	
 305	context->certificate = true;
 306	
 307	return true;
 308#else
 309	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
 310	
 311	return false;
 312#endif
 313}
 314
 315
 316
 317wi_boolean_t wi_socket_context_set_ssl_privkey(wi_socket_context_t *context, wi_string_t *path) {
 318#ifdef WI_SSL
 319	FILE		*fp;
 320	
 321	fp = fopen(wi_string_cstring(path), "r");
 322	
 323	if(!fp) {
 324		wi_error_set_errno(errno);
 325		
 326		return false;
 327	}
 328		
 329	context->priv_rsa = PEM_read_RSAPrivateKey(fp, NULL, 0, NULL);
 330	
 331	if(!context->priv_rsa)
 332		wi_error_set_ssl_error();
 333	
 334	fclose(fp);
 335	
 336	return (context->priv_rsa != NULL);
 337#else
 338	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
 339	
 340	return false;
 341#endif
 342}
 343
 344
 345
 346void wi_socket_context_set_ssl_pubkey(wi_socket_context_t *context, void *rsa) {
 347#ifdef WI_SSL
 348	if(context->pub_rsa != rsa) {
 349		if(context->pub_rsa)
 350			RSA_free(context->pub_rsa);
 351		
 352		context->pub_rsa = rsa;
 353	}
 354#endif
 355}
 356
 357
 358
 359wi_boolean_t wi_socket_context_set_ssl_ciphers(wi_socket_context_t *context, wi_string_t *ciphers) {
 360#ifdef WI_SSL
 361	if(SSL_CTX_set_cipher_list(context->ssl_ctx, wi_string_cstring(ciphers)) != 1) {
 362		wi_error_set_lib_error(WI_ERROR_SOCKET_NOVALIDCIPHER);
 363
 364		return false;
 365	}
 366	
 367	return true;
 368#else
 369	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
 370	
 371	return false;
 372#endif
 373}
 374
 375
 376
 377wi_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) {
 378#ifdef WI_SSL
 379	context->dh = DH_new();
 380	
 381	if(!context->dh) {
 382		wi_error_set_ssl_error();
 383
 384		return false;
 385	}
 386
 387	context->dh->p = BN_bin2bn(p, p_size, NULL);
 388	context->dh->g = BN_bin2bn(g, g_size, NULL);
 389
 390	if(!context->dh->p || !context->dh->g) {
 391		wi_error_set_ssl_error();
 392
 393		DH_free(context->dh);
 394		context->dh = NULL;
 395		
 396		return false;
 397	}
 398	
 399	return true;
 400#else
 401	wi_error_set_lib_error(WI_ERROR_SOCKET_NOSSL);
 402	
 403	return false;
 404#endif
 405}
 406
 407
 408
 409#pragma mark -
 410
 411wi_runtime_id_t wi_socket_runtime_id(void) {
 412	return _wi_socket_runtime_id;
 413}
 414
 415
 416
 417#pragma mark -
 418
 419wi_socket_t * wi_socket_alloc(void) {
 420	return wi_runtime_create_instance(_wi_socket_runtime_id, sizeof(wi_socket_t));
 421}
 422
 423
 424
 425wi_socket_t * wi_socket_init_with_address(wi_socket_t *_socket, wi_address_t *address, wi_socket_type_t type) {
 426	_socket->address	= wi_copy(address);
 427	_socket->close		= true;
 428	_socket->buffer		= wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
 429	_socket->type		= type;
 430
 431	_socket->sd			= socket(wi_address_family(_socket->address), _socket->type, 0);
 432	
 433	if(_socket->sd < 0) {
 434		wi_error_set_errno(errno);
 435		
 436		wi_release(_socket);
 437		
 438		return NULL;
 439	}
 440	
 441	if(!_wi_socket_set_option(_socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
 442		wi_release(_socket);
 443		
 444		return NULL;
 445	}
 446
 447	return _socket;
 448}
 449
 450
 451
 452wi_socket_t * wi_socket_init_with_descriptor(wi_socket_t *socket, int sd) {
 453	socket->sd			= sd;
 454	socket->buffer		= wi_string_init_with_capacity(wi_string_alloc(), WI_SOCKET_BUFFER_SIZE);
 455	
 456	return socket;
 457}
 458
 459
 460
 461static void _wi_socket_dealloc(wi_runtime_instance_t *instance) {
 462	wi_socket_t		*socket = instance;
 463	
 464	wi_socket_close(socket);
 465	
 466	wi_release(socket->address);
 467	wi_release(socket->buffer);
 468}
 469
 470
 471
 472static wi_string_t * _wi_socket_description(wi_runtime_instance_t *instance) {
 473	wi_socket_t		*socket = instance;
 474
 475	return wi_string_with_format(WI_STR("<%s %p>{sd = %d, address = %@}"),
 476		wi_runtime_class_name(socket),
 477		socket,
 478		socket->sd,
 479		socket->address);
 480}
 481
 482
 483
 484#pragma mark -
 485
 486static wi_boolean_t _wi_socket_set_option(wi_socket_t *socket, int level, int name, int option) {
 487	if(setsockopt(socket->sd, level, name, &option, sizeof(option)) < 0) {
 488		wi_error_set_errno(errno);
 489		
 490		return false;
 491	}
 492	
 493	return true;
 494}
 495
 496
 497
 498static wi_boolean_t _wi_socket_get_option(wi_socket_t *socket, int level, int name, int *option) {
 499	socklen_t		length;
 500	
 501	length = sizeof(*option);
 502	
 503	if(getsockopt(socket->sd, level, name, option, &length) < 0) {
 504		wi_error_set_errno(errno);
 505		
 506		*option = 0;
 507		
 508		return false;
 509	}
 510	
 511	return true;
 512}
 513
 514
 515
 516#pragma mark -
 517
 518wi_address_t * wi_socket_address(wi_socket_t *socket) {
 519	return socket->address;
 520}
 521
 522
 523
 524int wi_socket_descriptor(wi_socket_t *socket) {
 525	return socket->sd;
 526}
 527
 528
 529
 530void * wi_socket_ssl(wi_socket_t *socket) {
 531#ifdef WI_SSL
 532	return socket->ssl;
 533#else
 534	return NULL;
 535#endif
 536}
 537
 538
 539
 540void * wi_socket_ssl_pubkey(wi_socket_t *socket) {
 541#ifdef WI_SSL
 542	RSA			*rsa = NULL;
 543	X509		*x509 = NULL;
 544	EVP_PKEY	*pkey = NULL;
 545
 546	x509 = SSL_get_peer_certificate(socket->ssl);
 547
 548	if(!x509) {
 549		wi_error_set_ssl_error();
 550		
 551		goto end;
 552	}
 553	
 554	pkey = X509_get_pubkey(x509);
 555	
 556	if(!pkey) {
 557		wi_error_set_ssl_error();
 558
 559		goto end;
 560	}
 561	
 562	rsa = EVP_PKEY_get1_RSA(pkey);
 563	
 564	if(!rsa)
 565		wi_error_set_ssl_error();
 566
 567end:
 568	if(x509)
 569		X509_free(x509);
 570	
 571	if(pkey)
 572		EVP_PKEY_free(pkey);
 573	
 574	return rsa;
 575#else
 576	return NULL;
 577#endif
 578}
 579
 580
 581
 582wi_string_t * wi_socket_cipher_version(wi_socket_t *socket) {
 583#ifdef WI_SSL
 584	return wi_string_with_cstring(SSL_get_cipher_version(socket->ssl));
 585#else
 586	return NULL;
 587#endif
 588}
 589
 590
 591
 592wi_string_t * wi_socket_cipher_name(wi_socket_t *socket) {
 593#ifdef WI_SSL
 594	return wi_string_with_cstring(SSL_get_cipher_name(socket->ssl));
 595#else
 596	return NULL;
 597#endif
 598}
 599
 600
 601
 602uint32_t wi_socket_cipher_bits(wi_socket_t *socket) {
 603#ifdef WI_SSL
 604	return SSL_get_cipher_bits(socket->ssl, NULL);
 605#else
 606	return 0;
 607#endif
 608}
 609
 610
 611
 612wi_string_t * wi_socket_certificate_name(wi_socket_t *socket) {
 613#ifdef WI_SSL
 614	X509			*x509 = NULL;
 615	EVP_PKEY		*pkey = NULL;
 616	wi_string_t		*string = NULL;
 617
 618	x509 = SSL_get_peer_certificate(socket->ssl);
 619
 620	if(!x509)
 621		goto end;
 622
 623	pkey = X509_get_pubkey(x509);
 624
 625	if(!pkey)
 626		goto end;
 627	
 628	switch(EVP_PKEY_type(pkey->type)) {
 629		case EVP_PKEY_RSA:
 630			string = wi_string_init_with_cstring(wi_string_alloc(), "RSA");
 631			break;
 632
 633		case EVP_PKEY_DSA:
 634			string = wi_string_init_with_cstring(wi_string_alloc(), "DSA");
 635			break;
 636
 637		case EVP_PKEY_DH:
 638			string = wi_string_init_with_cstring(wi_string_alloc(), "DH");
 639			break;
 640
 641		default:
 642			break;
 643	}
 644	
 645end:
 646	if(x509)
 647		X509_free(x509);
 648
 649	if(pkey)
 650		EVP_PKEY_free(pkey);
 651
 652	return wi_autorelease(string);
 653#else
 654	return NULL;
 655#endif
 656}
 657
 658
 659
 660uint32_t wi_socket_certificate_bits(wi_socket_t *socket) {
 661#ifdef WI_SSL
 662	X509			*x509 = NULL;
 663	EVP_PKEY		*pkey = NULL;
 664	uint32_t		bits = 0;
 665
 666	x509 = SSL_get_peer_certificate(socket->ssl);
 667
 668	if(!x509)
 669		goto end;
 670
 671	pkey = X509_get_pubkey(x509);
 672
 673	if(!pkey)
 674		goto end;
 675	
 676	bits = 8 * EVP_PKEY_size(pkey);
 677	
 678end:
 679	if(x509)
 680		X509_free(x509);
 681
 682	if(pkey)
 683		EVP_PKEY_free(pkey);
 684
 685	return bits;
 686#else
 687	return 0;
 688#endif
 689}
 690
 691
 692
 693wi_string_t * wi_socket_certificate_hostname(wi_socket_t *socket) {
 694#ifdef WI_SSL
 695	X509			*x509;
 696	wi_string_t		*string;
 697	char			hostname[MAXHOSTNAMELEN];
 698
 699	x509 = SSL_get_peer_certificate(socket->ssl);
 700
 701	if(!x509)
 702		return NULL;
 703
 704	X509_NAME_get_text_by_NID(X509_get_subject_name(x509),
 705							  NID_commonName,
 706							  hostname,
 707							  sizeof(hostname));
 708	
 709	string = wi_string_init_with_cstring(wi_string_alloc(), hostname);
 710	
 711	X509_free(x509);
 712	
 713	return wi_autorelease(string);
 714#else
 715	return NULL;
 716#endif
 717}
 718
 719
 720
 721#pragma mark -
 722
 723void wi_socket_set_port(wi_socket_t *socket, uint32_t port) {
 724	wi_address_set_port(socket->address, port);
 725}
 726
 727
 728
 729uint32_t wi_socket_port(wi_socket_t *socket) {
 730	return wi_address_port(socket->address);
 731}
 732
 733
 734
 735void wi_socket_set_direction(wi_socket_t *socket, uint32_t direction) {
 736	socket->direction = direction;
 737}
 738
 739
 740
 741uint32_t wi_socket_direction(wi_socket_t *socket) {
 742	return socket->direction;
 743}
 744
 745
 746
 747void wi_socket_set_data(wi_socket_t *socket, void *data) {
 748	socket->data = data;
 749}
 750
 751
 752
 753void * wi_socket_data(wi_socket_t *socket) {
 754	return socket->data;
 755}
 756
 757
 758
 759
 760void wi_socket_set_blocking(wi_socket_t *socket, wi_boolean_t blocking) {
 761	int		flags;
 762
 763	flags = fcntl(socket->sd, F_GETFL);
 764
 765	if(flags < 0) {
 766		wi_error_set_errno(errno);
 767
 768		return;
 769	}
 770
 771	if(blocking)
 772		flags &= ~O_NONBLOCK;
 773	else
 774		flags |= O_NONBLOCK;
 775
 776	if(fcntl(socket->sd, F_SETFL, flags) < 0) {
 777		wi_error_set_errno(errno);
 778
 779		return;
 780	}
 781}
 782
 783
 784
 785wi_boolean_t wi_socket_blocking(wi_socket_t *socket) {
 786	int		flags;
 787	
 788	flags = fcntl(socket->sd, F_GETFL);
 789		
 790	if(flags < 0) {
 791		wi_error_set_errno(errno);
 792
 793		return false;
 794	}
 795	
 796	return !(flags & O_NONBLOCK);
 797}
 798
 799
 800
 801void wi_socket_set_interactive(wi_socket_t *socket, wi_boolean_t interactive) {
 802	if(socket->type == WI_SOCKET_TCP && interactive)
 803		_wi_socket_set_option(socket, IPPROTO_TCP, TCP_NODELAY, 1);
 804	
 805	if(wi_address_family(socket->address) == WI_ADDRESS_IPV4)
 806		_wi_socket_set_option(socket, IPPROTO_IP, IP_TOS, interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT);
 807	
 808	socket->interactive = interactive;
 809}
 810
 811
 812
 813wi_boolean_t wi_socket_interactive(wi_socket_t *socket) {
 814	return socket->interactive;
 815}
 816
 817
 818
 819int wi_socket_error(wi_socket_t *socket) {
 820	int		error;
 821	
 822	WI_ASSERT(socket->type == WI_SOCKET_TCP, "%@ is not a TCP socket", socket);
 823	
 824	if(!_wi_socket_get_option(socket, SOL_SOCKET, SO_ERROR, &error))
 825		return errno;
 826	
 827	return error;
 828}
 829
 830
 831
 832#pragma mark -
 833
 834wi_socket_t * wi_socket_wait_multiple(wi_list_t *list, wi_time_interval_t timeout) {
 835	wi_list_node_t		*node;
 836	wi_socket_t			*socket, *accept_socket;
 837	struct timeval		tv;
 838	fd_set				rfds, wfds;
 839	int					state, max_sd;
 840
 841	tv = wi_dtotv(timeout);
 842	max_sd = -1;
 843
 844	FD_ZERO(&rfds);
 845	FD_ZERO(&wfds);
 846
 847	wi_list_rdlock(list);
 848	WI_LIST_FOREACH(list, node, socket) {
 849		if(socket->direction & WI_SOCKET_READ)
 850			FD_SET(socket->sd, &rfds);
 851
 852		if(socket->direction & WI_SOCKET_WRITE)
 853			FD_SET(socket->sd, &wfds);
 854
 855		if(socket->sd > max_sd)
 856			max_sd = socket->sd;
 857	}
 858	wi_list_unlock(list);
 859	
 860	state = select(max_sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
 861	
 862	if(state < 0) {
 863		wi_error_set_errno(errno);
 864
 865		return NULL;
 866	}
 867	
 868	accept_socket = NULL;
 869	
 870	wi_list_rdlock(list);
 871	WI_LIST_FOREACH(list, node, socket) {
 872		if(FD_ISSET(socket->sd, &rfds) || FD_ISSET(socket->sd, &wfds)) {
 873			accept_socket = socket;
 874
 875			break;
 876		}
 877	}
 878	wi_list_unlock(list);
 879	
 880	return accept_socket;
 881}
 882
 883
 884
 885wi_boolean_t wi_socket_wait(wi_socket_t *socket, wi_time_interval_t timeout) {
 886	return wi_socket_wait_descriptor(socket->sd,
 887									 timeout,
 888									 (socket->direction & WI_SOCKET_READ),
 889									 (socket->direction & WI_SOCKET_WRITE));
 890}
 891
 892
 893
 894wi_boolean_t wi_socket_wait_descriptor(int sd, wi_time_interval_t timeout, wi_boolean_t read, wi_boolean_t write) {
 895	struct timeval	tv;
 896	fd_set			rfds, wfds;
 897	int				state;
 898	
 899	tv = wi_dtotv(timeout);
 900	
 901	FD_ZERO(&rfds);
 902	FD_ZERO(&wfds);
 903	
 904	if(read)
 905		FD_SET(sd, &rfds);
 906	
 907	if(write)
 908		FD_SET(sd, &wfds);
 909	
 910	state = select(sd + 1, &rfds, &wfds, NULL, (timeout > 0.0) ? &tv : NULL);
 911	
 912	if(state < 0)
 913		wi_error_set_errno(errno);
 914	else if(state == 0)
 915		wi_error_set_errno(ETIMEDOUT);
 916	
 917	return (state > 0);
 918}
 919
 920
 921
 922#pragma mark -
 923
 924wi_boolean_t wi_socket_listen(wi_socket_t *_socket, uint32_t backlog) {
 925	struct sockaddr		*sa;
 926	uint32_t			length;
 927	
 928	sa		= wi_address_sa(_socket->address);
 929	length	= wi_address_sa_length(_socket->address);
 930	
 931	if(bind(_socket->sd, sa, length) < 0) {
 932		wi_error_set_errno(errno);
 933		
 934		return false;
 935	}
 936
 937	if(_socket->type == WI_SOCKET_TCP) {
 938		if(listen(_socket->sd, backlog) < 0) {
 939			wi_error_set_errno(errno);
 940
 941			return false;
 942		}
 943	}
 944	
 945	_socket->direction = WI_SOCKET_READ;
 946	
 947	return true;
 948}
 949
 950
 951
 952wi_boolean_t wi_socket_connect(wi_socket_t *socket, wi_socket_context_t *context, wi_time_interval_t timeout) {
 953	struct sockaddr		*sa;
 954	uint32_t			length;
 955	int					state, err;
 956#ifdef WI_SSL
 957	int					ret;
 958#endif
 959	wi_boolean_t		blocking;
 960	
 961	blocking = wi_socket_blocking(socket);
 962
 963	if(blocking)
 964		wi_socket_set_blocking(socket, false);
 965	
 966	sa		= wi_address_sa(socket->address);
 967	length	= wi_address_sa_length(socket->address);
 968
 969	err		= connect(socket->sd, sa, length);
 970	
 971	if(err < 0) {
 972		if(errno != EINPROGRESS) {
 973			wi_error_set_errno(errno);
 974			
 975			return false;
 976		}
 977		
 978		do {
 979			state = wi_socket_wait_descriptor(socket->sd, 1.0, true, true);
 980			timeout -= 1.0;
 981		} while(state == 0 && timeout >= 0.0);
 982		
 983		if(state < 0)
 984			return false;
 985		
 986		if(timeout <= 0.0) {
 987			wi_error_set_errno(ETIMEDOUT);
 988			
 989			return false;
 990		}
 991		
 992		err = wi_socket_error(socket);
 993		
 994		if(err != 0) {
 995			wi_error_set_errno(err);
 996			
 997			return false;
 998		}
 999	}
1000
1001#ifdef WI_SSL
1002	if(context && context->ssl_ctx) {
1003		socket->ssl = SSL_new(context->ssl_ctx);
1004		
1005		if(!socket->ssl) {
1006			wi_error_set_ssl_error();
1007			
1008			return false;
1009		}
1010		
1011		if(SSL_set_fd(socket->ssl, socket->sd) != 1) {
1012			wi_error_set_ssl_error();
1013
1014			return false;
1015		}
1016		
1017		ret = SSL_connect(socket->ssl);
1018		
1019		if(ret != 1) {
1020			do {
1021				err = SSL_get_error(socket->ssl, ret);
1022
1023				if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
1024					wi_error_set_ssl_error();
1025					
1026					return false;
1027				}
1028				
1029				state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE));
1030				
1031				if(state < 0)
1032					break;
1033				
1034				if(state > 0) {
1035					ret = SSL_connect(socket->ssl);
1036					
1037					if(ret == 1)
1038						break;
1039				}
1040				
1041				timeout -= 1.0;
1042			} while(timeout >= 0.0);
1043			
1044			if(state < 0)
1045				return false;
1046			
1047			if(timeout <= 0.0) {
1048				wi_error_set_errno(ETIMEDOUT);
1049				
1050				return false;
1051			}
1052		}
1053	}
1054#endif
1055
1056	if(blocking)
1057		wi_socket_set_blocking(socket, true);
1058
1059	socket->direction = WI_SOCKET_READ;
1060	
1061	return true;
1062}
1063
1064
1065
1066wi_socket_t * wi_socket_accept_multiple(wi_list_t *list, wi_socket_context_t *context, wi_time_interval_t timeout, wi_address_t **address) {
1067	wi_socket_t		*socket;
1068	
1069	*address = NULL;
1070	socket = wi_socket_wait_multiple(list, 0.0);
1071	
1072	if(!socket)
1073		return NULL;
1074	
1075	return wi_socket_accept(socket, context, timeout, address);
1076}
1077
1078
1079
1080wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_socket_context_t *context, wi_time_interval_t timeout, wi_address_t **address) {
1081	wi_socket_t					*socket;
1082#ifdef WI_SSL
1083	SSL							*ssl = NULL;
1084#endif
1085	struct sockaddr_storage		ss;
1086	socklen_t					length;
1087	int							sd;
1088	
1089	length = sizeof(ss);
1090	sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length);
1091	
1092	*address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
1093
1094	if(sd < 0) {
1095		wi_error_set_errno(errno);
1096		
1097		goto err;
1098	}
1099	
1100#ifdef WI_SSL
1101	if(context && context->ssl_ctx) {
1102		ssl = SSL_new(context->ssl_ctx);
1103
1104		if(!ssl) {
1105			wi_error_set_ssl_error();
1106			
1107			goto err;
1108		}
1109
1110		if(SSL_set_fd(ssl, sd) != 1) {
1111			wi_error_set_ssl_error();
1112			
1113			goto err;
1114		}
1115
1116		if(!context->certificate && context->dh) {
1117			if(SSL_set_tmp_dh(ssl, context->dh) != 1) {
1118				wi_error_set_ssl_error();
1119				
1120				goto err;
1121			}
1122		}
1123		
1124		if(timeout > 0.0) {
1125			if(wi_socket_wait_descriptor(sd, timeout, true, false) <= 0)
1126				goto err;
1127		}
1128
1129		if(SSL_accept(ssl) != 1) {
1130			wi_error_set_ssl_error();
1131			
1132			goto err;
1133		}
1134	}
1135#endif
1136
1137	socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd);
1138
1139	socket->close		= true;
1140	socket->address		= wi_retain(*address);
1141	socket->type		= accept_socket->type;
1142	socket->direction	= WI_SOCKET_READ;
1143	socket->interactive	= accept_socket->interactive;
1144
1145#ifdef WI_SSL
1146	socket->ssl			= ssl;
1147#endif
1148	
1149	return wi_autorelease(socket);
1150	
1151err:
1152#ifdef WI_SSL
1153	if(ssl)
1154		SSL_free(ssl);
1155#endif
1156
1157	if(sd >= 0)
1158		close(sd);
1159
1160	return NULL;
1161}
1162
1163
1164
1165void wi_socket_close(wi_socket_t *socket) {
1166#ifdef WI_SSL
1167	if(socket->ssl) {
1168		if(!socket->broken) {
1169			if(SSL_shutdown(socket->ssl) == 0)
1170				SSL_shutdown(socket->ssl);
1171		}
1172
1173		SSL_free(socket->ssl);
1174		
1175		socket->ssl = NULL;
1176	}
1177#endif
1178
1179	if(socket->close && socket->sd >= 0) {
1180		close(socket->sd);
1181		
1182		socket->sd = -1;
1183	}
1184}
1185
1186
1187
1188#pragma mark -
1189
1190int32_t wi_socket_sendto(wi_socket_t *socket, wi_socket_context_t *context, wi_string_t *fmt, ...) {
1191	wi_string_t		*string;
1192	int				bytes;
1193	va_list			ap;
1194
1195	va_start(ap, fmt);
1196	string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
1197	va_end(ap);
1198
1199	bytes = wi_socket_sendto_buffer(socket, context, wi_string_cstring(string), wi_string_length(string));
1200	
1201	wi_release(string);
1202
1203	return bytes;
1204}
1205
1206
1207
1208int32_t wi_socket_sendto_buffer(wi_socket_t *socket, wi_socket_context_t *context, const char *buffer, size_t length) {
1209	wi_address_t	*address;
1210	char			*outbuffer = NULL;
1211	int				bytes;
1212	
1213	address = wi_socket_address(socket);
1214
1215#ifdef WI_SSL
1216	if(context && context->pub_rsa) {
1217		outbuffer = wi_malloc(RSA_size(context->pub_rsa));
1218		bytes = RSA_public_encrypt(length, (unsigned char *) buffer, (unsigned char *) outbuffer,
1219			context->pub_rsa, RSA_PKCS1_OAEP_PADDING);
1220		
1221		if(bytes < 0) {
1222			wi_error_set_ssl_error();
1223			
1224			goto end;
1225		}
1226		
1227		bytes = sendto(socket->sd, outbuffer, bytes, 0,
1228			wi_address_sa(address), wi_address_sa_length(address));
1229	} else {
1230#endif
1231		bytes = sendto(socket->sd, buffer, length, 0,
1232			wi_address_sa(address), wi_address_sa_length(address));
1233#ifdef WI_SSL
1234	}
1235#endif
1236	
1237	if(bytes < 0) {
1238		wi_error_set_errno(errno);
1239		
1240		goto end;
1241	}
1242
1243end:
1244	if(outbuffer)
1245		wi_free(outbuffer);
1246	
1247	return bytes;
1248}
1249
1250
1251
1252int32_t wi_socket_recvfrom_multiple(wi_list_t *list, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) {
1253	wi_socket_t		*socket;
1254	
1255	*address = NULL;
1256	socket = wi_socket_wait_multiple(list, 0.0);
1257	
1258	if(!socket)
1259		return -1;
1260	
1261	return wi_socket_recvfrom(socket, context, buffer, length, address);
1262}
1263
1264
1265
1266int32_t wi_socket_recvfrom(wi_socket_t *socket, wi_socket_context_t *context, char *buffer, size_t length, wi_address_t **address) {
1267	struct sockaddr_storage		ss;
1268	char						*inbuffer = NULL;
1269	socklen_t					sslength;
1270	int							bytes;
1271	
1272	sslength = sizeof(ss);
1273	
1274#ifdef WI_SSL
1275	if(context && context->priv_rsa) {
1276		inbuffer = wi_malloc(length);
1277		bytes = recvfrom(socket->sd, inbuffer, length, 0, (struct sockaddr *) &ss, &sslength);
1278		
1279		if(bytes < 0) {
1280			wi_error_set_errno(errno);
1281			
1282			goto end;
1283		}
1284		
1285		bytes = RSA_private_decrypt(bytes, (unsigned char *) inbuffer, (unsigned char *) buffer,
1286			context->priv_rsa, RSA_PKCS1_OAEP_PADDING);
1287		
1288		if(bytes < 0) {
1289			wi_error_set_ssl_error();
1290
1291			goto end;
1292		}
1293	} else {
1294#endif
1295		bytes = recvfrom(socket->sd, buffer, length, 0, (struct sockaddr *) &ss, &sslength);
1296
1297		if(bytes < 0) {
1298			wi_error_set_errno(errno);
1299			
1300			goto end;
1301		}
1302#ifdef WI_SSL
1303	}
1304#endif
1305
1306end:
1307	*address = (sslength > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL;
1308
1309	if(inbuffer)
1310		wi_free(inbuffer);
1311
1312	return bytes;
1313}
1314
1315
1316
1317#pragma mark -
1318
1319int32_t wi_socket_write(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *fmt, ...) {
1320	wi_string_t		*string;
1321	int				bytes;
1322	va_list			ap;
1323
1324	va_start(ap, fmt);
1325	string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap);
1326	va_end(ap);
1327	
1328	bytes = wi_socket_write_buffer(socket, timeout, wi_string_cstring(string), wi_string_length(string));
1329	
1330	wi_release(string);
1331
1332	return bytes;
1333}
1334
1335
1336
1337int32_t wi_socket_write_buffer(wi_socket_t *socket, wi_time_interval_t timeout, const void *buffer, size_t length) {
1338	int		bytes;
1339	
1340	if(timeout > 0.0) {
1341		if(wi_socket_wait_descriptor(socket->sd, timeout, false, true) <= 0)
1342			return -1;
1343	}
1344
1345#ifdef WI_SSL
1346	if(socket->ssl) {
1347		bytes = SSL_write(socket->ssl, buffer, length);
1348
1349		if(bytes < 0) {
1350			wi_error_set_ssl_error();
1351
1352			socket->broken = true;
1353		}
1354	} else {
1355#endif
1356		bytes = write(socket->sd, buffer, length);
1357		
1358		if(bytes < 0)
1359			wi_error_set_errno(errno);
1360#ifdef WI_SSL
1361	}
1362#endif
1363	
1364	return bytes;
1365}
1366
1367
1368
1369wi_string_t * wi_socket_read(wi_socket_t *socket, wi_time_interval_t timeout, size_t length) {
1370	wi_string_t		*string;
1371	char			buffer[WI_SOCKET_BUFFER_SIZE];
1372	int				bytes = -1;
1373	
1374	string = wi_string_init_with_capacity(wi_string_alloc(), length);
1375	
1376	while(length > sizeof(buffer)) {
1377		bytes = wi_socket_read_buffer(socket, timeout, buffer, sizeof(buffer));
1378		
1379		if(bytes <= 0)
1380			goto end;
1381		
1382		wi_string_append_bytes(string, buffer, bytes);
1383		
1384		length -= bytes;
1385	}
1386
1387	if(length > 0) {
1388		bytes = wi_socket_read_buffer(socket, timeout, buffer, length);
1389		
1390		if(bytes <= 0)
1391			goto end;
1392		
1393		wi_string_append_bytes(string, buffer, bytes);
1394	}
1395
1396end:
1397	if(wi_string_length(string) == 0) {
1398		if(bytes < 0) {
1399			wi_release(string);
1400			
1401			string = NULL;
1402		}
1403	}
1404
1405	return wi_autorelease(string);
1406}
1407
1408
1409
1410wi_string_t * wi_socket_read_to_string(wi_socket_t *socket, wi_time_interval_t timeout, wi_string_t *separator) {
1411	wi_string_t		*string, *substring;
1412	uint32_t		index;
1413	
1414	index = wi_string_index_of_string(socket->buffer, separator, 0);
1415	
1416	if(index != WI_NOT_FOUND) {
1417		substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
1418		
1419		wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
1420
1421		return substring;
1422	}
1423	
1424	while((string = wi_socket_read(socket, timeout, WI_SOCKET_BUFFER_SIZE))) {
1425		if(wi_string_length(string) == 0)
1426			return string;
1427
1428		wi_string_append_string(socket->buffer, string);
1429
1430		index = wi_string_index_of_string(socket->buffer, separator, 0);
1431		
1432		if(index == WI_NOT_FOUND) {
1433			if(wi_string_length(socket->buffer) > _WI_SOCKET_BUFFER_MAX_SIZE) {
1434				substring = wi_string_substring_to_index(socket->buffer, _WI_SOCKET_BUFFER_MAX_SIZE);
1435
1436				wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
1437				
1438				return substring;
1439			}
1440		} else {
1441			substring = wi_string_substring_to_index(socket->buffer, index + wi_string_length(separator));
1442			
1443			wi_string_delete_characters_in_range(socket->buffer, wi_make_range(0, wi_string_length(substring)));
1444			
1445			return substring;
1446		}
1447	}
1448	
1449	return NULL;
1450}
1451
1452
1453
1454int32_t wi_socket_read_buffer(wi_socket_t *socket, wi_time_interval_t timeout, void *buffer, size_t length) {
1455	int		bytes;
1456	
1457	if(timeout > 0.0) {
1458#ifdef WI_SSL
1459		if(socket->ssl && SSL_pending(socket->ssl) == 0) {
1460#endif
1461			if(wi_socket_wait_descriptor(socket->sd, timeout, true, false) <= 0)
1462				return -1;
1463#ifdef WI_SSL
1464		}
1465#endif
1466	}
1467
1468#ifdef WI_SSL
1469	if(socket->ssl) {
1470		bytes = SSL_read(socket->ssl, buffer, length);
1471		
1472		if(bytes <= 0) {
1473			wi_error_set_ssl_error();
1474
1475			socket->broken = true;
1476		}
1477	} else {
1478#endif
1479		bytes = read(socket->sd, buffer, length);
1480		
1481		if(bytes < 0)
1482			wi_error_set_errno(errno);
1483		else if(bytes == 0)
1484			wi_error_set_lib_error(WI_ERROR_SOCKET_EOF);
1485#ifdef WI_SSL
1486	}
1487#endif
1488
1489	return bytes;
1490}