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

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

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