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

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

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